[討論] 這幾天我架了伺服器-如何將java最佳化?

看板 Minecraft
作者 miau9202 (Mr.M)
時間 2013-01-13 20:42:47
留言 16 ( 8推 0噓 8→ )
Can't keep up! Did the system time change, or is the server overload? 我相信,這訊息是所有伺服器主一生永遠的痛。 自去年開始架 Minecraft 伺服器開始,我即不斷地在找尋如何調校java的方法, 好讓伺服器能夠更順暢的運作,那時我有發一篇名為"降低延遲與修復破損的世界" 一篇翻譯自bukkit論壇上的調校文章。 不過效果不彰,雖然 Can't keep up! 減少了很多,遊戲卻頻頻停頓,最後索性放棄了。 但是這次,為了讓這些Forge MOD安分,還真讓我找到一篇真的能用的調校文。 在開始正文之前,我必須轉達一些來自bukkit論壇上版友們的警告: 一昧地遵照所謂的"調校教學"是大錯特錯的,因為不同的硬體有它不同的特性,所以各種 指令參數並非能在所有系統上面使用。而進行所謂的"調校",不應該僅把它當作一種"行 為",更應該慎重的把它當作是一門"藝術"。 ============================================================================== 以下翻譯自原文:(可能有翻譯不完整甚至是錯誤的地方,更正大歡迎) How can I optimize Java on my server? http://goo.gl/wyalw 請記住這篇文章是針對 Java6 而寫成。(按:現在已經是Java7)然而,大部分或者所有的 參數都能在Java7中運作,雖然實際情形可能跟本篇不同。 伺服器的規格是 Windows Server 2008 R2 SP1 64Bit Core i7 2600k 並超頻到 4.8Ghz, 16GB 的記憶體, 1GB 的 RAMDisk 這是我完整的啟動腳本(StartServer.cmd) @Echo OFF TITLE MINECRAFT-CRAFTBUKKIT START "MINECRAFT-CRAFTBUKKIT" /ABOVENORMAL /B java -server -Xmx12G -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseNUMA -XX:+CMSParallelRemarkEnabled -XX:MaxGCPauseMillis=50 -XX:+UseAdaptiveGCBoundary -XX:-UseGCOverheadLimit -XX:+UseBiasedLocking -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15 -XX:UseSSE=3 -XX:+UseLargePages -XX:+UseFastAccessorMethods -XX:+UseStringCache -XX:+UseCompressedStrings -XX:+UseCompressedOops -XX:+OptimizeStringConcat -XX:+AggressiveOpts -jar craftbukkit.jar nogui 如果想得到完整的 垃圾回收 (Garbage Collection) 的紀錄,要再加入以下參數 (注:垃圾回收是一種記憶體管理技術,詳情請自行查詢 wiki) -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -Xloggc:memory.log 注意!即使程式只運作一小段時間,也會產生非~常大的紀錄檔案,因為程式會擷取大量 的資料。通常也會多少影響伺服器效能,所以請在有需要解析垃圾回收的行為時再使用這 些參數。市面上有很多可以分析這個紀錄的分析工具,能產生完善的分析圖表。 你可以在這裡找到一個圖表分析工具: http://java.sun.com/developer/technicalArticles/Programming/GCPortal/index.html (已失效,文後補注) 接下來我們來逐步看看這些參數 @ Echo OFF TITLE MINECRAFT-CRAFTBUKKIT START "MINECRAFT-CRAFTBUKKIT" /ABOVENORMAL /B java -server 這幾行會啟動伺服器,並擁有比一般程式還要高的優先權,並指定要啟動伺服器版的JVM -Xmx12G -XX:PermSize=128m -XX:MaxPermSize=256m 指定JVM最多能動態分配的記憶體為12GB,這個數值必須小於實體記憶體的容量。但我不 指定JVM啟動時要配給多少記憶體給他,而是讓JVM自己決定要吃多少就吃多少。 我的伺服器有 16GB 的記憶體,所以剩下的 2GB 我留給系統。根據經驗,把最大實體記 憶體減掉 2GB 就是可以配給程式的大小。若是在獨立的Linux伺服器上,你則可以從系統 上挪用更多記憶體。 PermSize參數可以指定永久保存區域(Permanent Generation space,原文只提 Permanent)的起始與最大容量。我確信預設的大小是起始32MB與最大64MB。從垃圾回收的 紀錄來說,我常常看到他一路衝滿64MB,所以我設高一點好給JVM留點空間。雖然128MB不 怎麼節省就是了。 編按:一個jar內包含一個以上的class,從minecraft_server到forge甚至其他MOD總計的 class數量相當可觀。而這些class會先被載入到 Permanent Generation space,並不受 垃圾回收程序影響,唯有退出的class才會做垃圾處理。(根據手邊的資料,並沒有提及 PermGen滿了會做什麼事,只知道他累積到一定的量會停住並不會減少) -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseNUMA -XX:+CMSParallelRemarkEnabled 關閉完整垃圾回收來預防遊戲內長時間的暫停。 指定 concurrent mark sweep collector 來針對 old generation 進行垃圾回收,new generation 則指定 parallel collector 做垃圾回收。這一行同時也會讓回收垃圾的標 記過程做平行處理。最後,啟用 NUMA (這個請自己查) 做記憶體內物件放置最佳化來提 升效能。 -XX:MaxGCPauseMillis=50 這行告訴每一次進行回收而造成的暫停不能超過 50毫秒 。而現代的CPU做垃圾處理通 常平均低於 40毫秒 以下,所以設定為 50毫秒 有助於預防突然的運算高峰。而讓垃圾處 理所造成的暫停時間低於每 1 tick 的速度會有助於伺服器運作順暢。 另外,我讓 JVM 自己決定要使用多少線程來來做垃圾回收...等。因為只有他自己才知道 怎樣設定才是最好的。如果手動設定得太高或太低,只會弊大於利。 -XX:+UseAdaptiveGCBoundary -XX:-UseGCOverheadLimit -XX:+UseBiasedLocking 允許new generation與tenured generation之間的資料轉移 GCOverHeadLimit前面的減號代表把這個功能關掉。這會在輸出記憶體錯誤的訊息之前增 加垃圾處理的時間。因為伺服器不見得會照你的意思去做,所以我寧願多鞭策他個幾下 好讓他多釋放一點記憶體。 BiasedLocking should aid efficiency in multi CPU setups by biasing an objects to use the thread which first created it. (鎖什麼的最討厭了,不翻) -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15 讓物件在 new generation 中活久一點再丟進old generation。試著比對加入或移除這三 個參數所得到的結果。為了得到完善的測試結果,請進行長時間的測試,24小時或者更長 的時間。 -XX:UseSSE=3 -XX:+UseLargePages 允許使用大型記憶體分頁來增進效能。雖然這需要你的作業系統支援。Windows7支援,然 後大多數的Linux發行版也支援,但你可能需要事先在Linux上面做一些調整。沒有任何事 是Google不能幫你的。如果出現權限不足的情形,就需要以系統管理員的身分執行。 權限不足,使用系統管理員帳號把現在的帳號添加額外權限: 1. 到 控制台 -> 系統管理工具 -> 本機安全性原則 2. 選 本機原則 -> 使用者權限指定使用者權限指派 3. 在"鎖定記憶體分頁",新增 使用者 和/或 群組 4. 重新啟動電腦 -XX:+UseStringCache -XX:+UseCompressedStrings -XX:+Use CompressedOops -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+AggressiveOpts (注:Java7底下只要增加綠色的部分就可以了) 最佳化選項在 Java6 裡是預設關閉的,但其中部分選項可能已經在Java7中預設開啟。 這就是我對伺服器所做的調整內容,而且也運作得相當不錯。我只有同時最多 15 名玩家 在線上,所以我想知道那些容納 30 名以上玩家的大型伺服器用了這些參數之後會有怎樣 的結果。雖然目前大部分都是正面回應。 ============================================================================== 補述: 1. JVM 即是 Java Virtual Machine,簡單來說就是實際執行Java的東西叫這個名字。 2. 簡述Java的GC管理: Java對記憶體管理分:new, tenured(old), permanent generation 這三種區,新丟進記 憶體的會先劃分到new(新人加入),經過不斷的GC垃圾回收(淘汰不適任者),沒被回收的 就會丟到old(成為正職員工)。Permanent則是那些運作本體、MOD裡的各種class、字串丟 進去保存的地方(譬如各種專業顧問),基本上是不太會被GC的。 3. 垃圾回收記錄分析工具,我用過的有下面這兩種: (1). IBM Pattern Modeling and Analysis Tool for Java Garbage Collector: http://goo.gl/EBEpo (2). GCViewer: https://github.com/chewiebug/GCViewer/wiki/Changelog 我推薦 IBM 那款,直接看 Summary 看哪個Generation滿了就加大,哪個沒怎麼用就縮小 至於 GCViewer 他 PermSize 抓不到,不過可以用"WATCH"功能即時監看GC過程,還不錯。 若要產生支援上述軟體的紀錄檔。記得配合以下參數服用:(上面介紹的就不理他了吧) -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:memory.log 4. 附上我的電腦設備: CPU:AMD Athlon 64 X2 4000+ 2.1GHz 記憶體:DDR2 3GB 作業系統:Windows 7 家用進階版 32bit 以下是我的啟動參數 %JAVA% -server -Xmx1G -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseNUMA -XX:+CMSParallelRemarkEnabled -XX:+UseAdaptiveGCBoundary -XX:-UseGCOverheadLimit -XX:+UseBiasedLocking -XX:UseSSE=3 -XX:+OptimizeStringConcat -XX:+UseFastAccessorMethods -XX:+AggressiveOpts-jar minecraftforge-universal-1.4.6-6.5.0.471.jar nogui 跟上面的文章有差別的地方是,因為記憶體不多所以我不開大記憶體分頁,也不設定 SurvivorRatio,交給JVM自己決定。至於 PermSize 之類的參數,因為一直沒滿過所以就 沒特別設定了。跑的這幾天也證明,minecraft伺服器真的建議一定要有 1GB 以上的空閒 記憶體 (電腦至少要配備2GB以上的記憶體) 順便附上自己最近的GC紀錄: http://dl.dropbox.com/u/7320770/BBS/Minecraft/memory1.7z 希望上面的沒翻錯,也感謝大家看完這篇 XD 至於我以前發的那篇文章就忘了吧,那不是調校,是搞笑。 參考資料: http://goo.gl/OCMFM -- ※ 發信站: 批踢踢實業坊(ptt.cc)

留言

※ 編輯: miau9202 來自: 111.242.110.240 (01/13 20:47)
W22625231 借串偷問 請問伺服器端的成就資料儲存在哪阿QAQ? 01/13 20:59 1F
miau9202 我只知道玩家資料放在地圖資料夾底下的 player 資料夾 01/13 21:01 2F
miau9202 如果沒猜錯的話,成就是不放在伺服器的喔 01/13 21:02 3F
miau9202 請看 http//www.minecraftwiki.net/wiki/Statistics 01/13 21:03 4F
leemiyinghao 伺服器超頻...(汗 01/13 21:07 5F
W22625231 真的耶QwQ 感謝 01/13 21:09 6F
gh0987 在現在單機變內部伺服的情況之下 所以對單機也有效? 01/13 21:17 7F
W22625231 可以伸懶人包嗎(死 01/13 21:19 8F
miau9202 這篇的用意是加強記憶體管理,對單機應該有效。 01/13 21:35 9F
miau9202 還有這不是超頻 _A_ 這東西沒懶人包,如果不懂建議別用 01/13 21:37 10F
leemiyinghao 不,我指的是i7 2600k拉到4.8G那邊(汗 01/13 21:57 11F
miau9202 呃............人家老外心臟很大顆別介意... 01/13 22:19 12F
i56821123 看到老外心臟很大顆我只能推了... 01/13 22:50 13F
※ 編輯: miau9202 來自: 111.242.110.240 (01/13 23:46)
t19910422 快推 不然人家以為我們看不懂 01/13 23:57 14F
mmis1000 i7 2600 3.4 up to 3.8 ghz,多超0.8ghz,真不怕燒掉= = 01/14 00:53 15F
tsukie2887 散熱有做好的話 2600K大多都拉到近5G吧 ?_? 01/14 00:55 16F

最新文章

[XBOX] 徵 XBOX Series X主機
gamesale cyhscat
2024-11-19 07:13:34
[閒聊] 11/19閒聊
nba_fantasy magicjohnson
2024-11-19 06:45:04
[絕區] 卡呂冬之子是不是偷作弊
mihoyo clawrage
2024-11-19 05:36:00
[百抽] 第九次傳說百抽
summonerswar uoieau
2024-11-19 05:01:20
Re: [心得] 奧術前六集觀後感
lol jeff11503
2024-11-19 04:36:35
[情報] TGA遊戲大賞(LOL相關)
20 27 lol snakek
2024-11-19 03:19:47
[閒聊] ARAM的分配機制是不是怪怪的?
9 15 lol airbear
2024-11-19 03:18:49
[NS ] 徵 賽馬娘
gamesale song
2024-11-19 01:59:02
[閒聊] GENG的一些乳摸
48 125 lol e2042422
2024-11-19 01:42:01
[NS ] 售 Switch 充電座
gamesale alphanumeric
2024-11-19 01:25:31
[PS5 ] 售 樂高地平線
gamesale monsuta
2024-11-19 00:58:14