Java垃圾收集器导致大量延迟

Java垃圾收集器导致大量延迟,java,garbage-collection,Java,Garbage Collection,每当控制台中出现以下消息时,我都会注意到我的游戏有很大的延迟 [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

每当控制台中出现以下消息时,我都会注意到我的游戏有很大的延迟

[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收集的对象的类

减少垃圾收集时间最有效的方法就是减少垃圾量,这是显而易见的

您可以使用像JvisualVM(JDK附带)这样的探查器来查看您的程序如何使用分配给它的内存,以及在垃圾收集上花费了多少时间


在游戏程序中,您需要一致的帧速率:您需要重构代码,以便尽可能多地重用对象,而不是创建新对象并允许稍后收集它们(这将在不可避免地需要垃圾收集时导致明显的延迟峰值)。(不幸的是,这就是为什么像Java这样的内存管理语言不是游戏的最佳语言。)

哪个JVM版本?您正在使用哪个GC(G1?)?您总共分配了多少堆内存?(最后一个是nm,我看到您在那里列出了它。)当您看到这些GC事件时,必须进行分析并捕获多个堆转储。分析这些转储并查看导致内存泄漏的最大对象。然后你可以修改代码来修复漏洞。对于如此小的堆大小,这些都是令人费解的高暂停。同样奇怪的是,在一个年轻的gc已经回收了足够多的内存之后,JVM执行了一个毫无意义的完全gc。对于这样一个小的堆,使用并行gc可能弊大于利。但无论如何,既然您似乎是在Java8或更高版本下运行的,那么请尝试另一种gc算法,例如G1.Thank。是的,你说得对,我用的是Java8。使用更高版本的Java会有所不同吗?我曾经尝试过使用G1,但是没有任何明显的改进。我认为,我的代码中存在导致问题的任何问题,我必须按照@RahulVedpathak的建议来解决问题。当我们不知道问题的实际原因时,很难说不同的Java版本是否会改变任何东西。我想,这个问题可能与JVM完全无关,是由交换等平台问题引起的。我发现我总是在代码中创建向量类的新实例。在每个类中都有一个或两个静态字段,以便这些向量能够重用它们,这是一种可能的方式吗?@DasElias可能——是的;但关于功能的准确性,我建议您单独提出一个问题,并提供更详细的答案。