【发布时间】:2019-09-14 03:17:43
【问题描述】:
每次,当控制台中出现以下消息时,我都会注意到我的游戏出现了很大的延迟。
[GC (Allocation Failure)
Desired survivor size 133693440 bytes, new threshold 7 (max 15)
[PSYoungGen: 916500K->130553K(918016K)] 1018868K->444063K(1232384K), 1.2505777 secs] [Times: user=1.87 sys=0.43, real=1.25 secs]
[Full GC (Ergonomics) [PSYoungGen: 130553K->127049K(918016K)] [ParOldGen: 313509K->314172K(555008K)] 444063K->441222K(1473024K), [Metaspace: 9374K->9374K(1058816K)], 3.7134878 secs]
我使用以下参数运行我的程序:
-Xms1024M
-Xmx2048M
-XstartOnFirstThread
-XX:+PrintGCDetails
-XX:+PrintClassHistogram
-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
有没有可能减少 GC 所需的时间?如何查看 GC 收集的对象的类?
【问题讨论】:
-
哪个JVM版本?您使用的是哪个 GC(G1?)?您分配了多少总堆内存? (在最后一个上,我看到你在那里列出了它。)
-
当您看到这些 GC 事件时,您必须进行分析并捕获多个堆转储。分析这些转储并查看导致内存泄漏的最大对象。然后您可以修改代码以修复泄漏。
-
对于如此小的堆大小来说,这些令人费解的高暂停。同样奇怪的是,在一个年轻的 gc 已经回收了足够多的内存之后,JVM 执行了一个毫无意义的完整 gc。也许,对于这么小的堆,使用并行 gc 弊大于利。但无论如何,由于您似乎在 Java 8 或更高版本下运行,只需尝试不同的 gc 算法,例如G1.
-
谢谢。是的,你是对的,我使用 Java 8。使用更高版本的 Java 会有什么不同吗?我曾尝试使用 G1,但它并没有带来任何明显的改进。我认为,我的代码中存在导致问题的任何问题,我必须像@RahulVedpathak 建议的那样解决问题。
-
当我们不知道问题的真正原因时,很难说不同的 Java 版本是否会改变任何东西。我猜,这个问题可能与 JVM 完全无关,是由交换等平台问题引起的。