啊,终于买了台新电脑了。
赶紧打开我最爱的 Minecraft 整合包。这下终于不会卡了吧?
怎么还是卡?我这个配置怎么可能卡呢?
如果你遇到下列情况,那很有可能不是因为你的硬件性能不行,而是 JVM 的垃圾回收在搞鬼。
Minecraft 启动后进入标题界面未响应、假死。 Minecraft 打开存档加载完地形时未响应、假死。 Minecraft 在加载大量区块时未响应、假死。 且以上问题都是暂时性的,等待一段时间后会回复,但是可能会频繁出现。
本篇教程适用于 8G RAM 以上的 64 位 Java 7u4 以上的 Minecraft 玩家。
(不到 8G RAM 也可以尝试,但是不保证效果)
你问我为什么不是 Java 8+?因为Java 8u20+ 与 Minecraft 1.6.4 Forge #965 的已知兼容性问题,导致 1.6.4 玩家只能在 Java 8u19- 下游玩。
竟然时隔多年更新了 Forge #1345 修复了这个问题,emmmm…你们爱用啥用啥吧…
好了废话不多说,先上参数:
-XX:+UseG1GC -Xms4G
-Dsun.rmi.dgc.server.gcInterval=2147483646
-XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M -XX:+AlwaysPreTouch
找到你的启动器中的 JVM Arugments、JVM 参数栏,把以上内容填入即可。
以上参数都是什么意思?
首先是使用这些参数的目的。垃圾回收 (Garbage collection) 是 JVM 虚拟机回收不再使用的对象的机制。而 GC 时候的停顿,是导致卡顿和假死的根源。
-XX:+UseG1GC
把垃圾优先型垃圾回收器(G1 Garbage Collector)作为当前的垃圾回收器。
The Garbage-First (G1) garbage collector is fully supported in Oracle JDK 7 update 4 and later releases. The G1 collector is a server-style garbage collector, targeted for multi-processor machines with large memories. It meets garbage collection (GC) pause time goals with high probability, while achieving high throughput. Whole-heap operations, such as global marking, are performed concurrently with the application threads. This prevents interruptions proportional to heap or live-data size.
-Xms4G
Java 虚拟机的初始化的堆空间大小设定。通常来说,你在启动器中设定的内存大小即为 JVM 虚拟机的堆大小。最好是将其与您的 Minecraft 设定的内存保持一致。(反正你也不会希望在运行的时候动态调整堆空间吧?)
-Dsun.rmi.dgc.server.gcInterval=2147483646
告诉 RMI 层不要每分钟做一次 GC。
由于默认值够长(1h),所以不再需要这个参数了。Ref.
-XX:+UnlockExperimentalVMOptions
解锁试验性 JVM 选项。嗯。
-XX:G1NewSizePercent=20
把新生代的内存设置为堆大小的 20%。这个值需要足够大,因为 JVM 会把新对象生成在这里。如果这个区域不够大,会导致这个区域满了之后开始 GC,导致许多微卡顿(现象是即使 fps 很不错,但是仍然感觉一顿一顿的有跳帧。按 Shift + F3 看详细信息,左下角的帧生成时间曲线不平滑,有许多尖峰)。而 Minecraft 会生成许多对象,尤其是加载区块的时候,而且视距越远越明显。
-XX:MaxGCPauseMillis=50
如果可能,让 JVM 尝试在 50ms 内完成 GC。为什么是 50ms?因为一般 Minecraft 以 20TPS (Ticks per second) 运行,即 50ms/Tick。若在一个 tick 内应有的操作没有处理完成,Minecraft 会试图拉长这个 Tick 让操作完成,导致卡顿(低TPS)。
-XX:G1HeapRegionSize=32M
这个选项涉及到 G1 GC 的工作原理。
G1 GC 是区域化、分代式垃圾回收器,这意味着 Java 对象堆(堆)被划分成大小相同的若干区域。启动时,Java 虚拟机 (JVM) 会设置区域大小。区域大小从 1 MB 到 32 MB 不等,具体取决于堆大小。目标是产生不超过 2048 个区域。Eden、存活空间和老年代是一系列不连续的逻辑区域。
更大的区域意味着更少的区域,同时意味着更少的垃圾回收时间。
根据这里,我们就把它设定成最大值 32M。
-XX:+AlwaysPreTouch
提前分配所有内存
好了。现在打开 Minecraft,愉快的玩耍吧!
ps:经 LittleWind404 提醒,发现一个整理这种 JVM 参数的网站:https://mcflags.emc.gs
pps:你可能也想找这个 https://server.properties/