Java JVM内存足够,但频率已满

Java JVM内存足够,但频率已满,java,garbage-collection,jvm,Java,Garbage Collection,Jvm,JVM选项: -Xms512M-Xmx512M-XX:PermSize=70M-XX:MaxPermSize=70M jstat-gc 8260 5000 S0C:512.0 S1C:512.0 S0U:0.0 S1U:0.0 EC:174080.0 EU:0.0 OC:349696.0 OU:45191.1 PC:71680.0 PU:34882.2 YGC:2216225 YGCT:6754.909 FGC:2216144 FGCT:160651.466 GCT:167406.375 S0C

JVM选项: -Xms512M-Xmx512M-XX:PermSize=70M-XX:MaxPermSize=70M

jstat-gc 8260 5000

S0C:512.0 S1C:512.0 S0U:0.0 S1U:0.0 EC:174080.0 EU:0.0 OC:349696.0 OU:45191.1 PC:71680.0 PU:34882.2 YGC:2216225 YGCT:6754.909 FGC:2216144 FGCT:160651.466 GCT:167406.375

S0C:512.0 S1C:512.0 S0U:0.0 S1U:64.0 EC:174080.0 EU:0.0 OC:349696.0 OU:45187.3 PC:71680.0 PU:34882.2 YGC:2216253 YGCT:6755.047 FGC:2216172 FGCT:160653.488 GCT:167408.535

S0C:512.0 S1C:512.0 S0U:0.0 S1U:128.0 EC:174080.0 EU:0.0 OC:349696.0 OU:45189.6 PC:71680.0 PU:34882.2 YGC:2216281 YGCT:6755.180 FGC:2216200 FGCT:160655.542 GCT:167410.721

S0C:512.0 S1C:512.0 S0U:0.0 S1U:0.0 EC:174080.0 EU:1775.6 OC:349696.0 OU:45187.3 PC:71680.0 PU:34882.2 YGC:2216308 YGCT:6755.309 FGC:221627 FGCT:160657.627 GCT:167412.936

S0C:512.0 S1C:512.0 S0U:128.0 S1U:0.0 EC:174080.0 EU:0.0 OC:349696.0 OU:45187.3 PC:71680.0 PU:34882.2 YGC:2216336 YGCT:6755.444 FGC:2216255 FGCT:160659.701 GCT:167415.146


为什么会发生JVM频率完全gc?

很难说,但一种可能的解释是,您正在重复分配和丢弃非常大的数组

如果我正确解释了统计数据,伊甸园空间是174MB,幸存者空间是0.5MB,旧空间是349MB。如果您分配的数组太大,无法放入Eden空间,它将直接分配到旧空间。如果旧空间已满,则可能会触发完整GC

“大”有多大?这很复杂,因为还有TLAB及其大小的问题,
-XX:precuresizethreshold
选项以及不同类型GC之间的差异。阅读Martin Thompson的文章,让您开始了解这些问题


如果这不是问题所在,那么您需要对堆中发生的情况进行更深入的调查。弄清楚对象的组合是什么,它们的速率和分配/处置模式等,尝试弄清楚为什么这么多对象最终会出现在旧空间中

3-5天工作正常后,就会发生这种情况


这往往表明,在这三到五天的操作过程中,应用程序内存中的数据结构正在积累一些东西。调查这种情况。

您的幸存者空间非常小。只有512KB。如果幸存者空间在清理伊甸园空间时被填满,它将触发一个完整的GC

由于您的伊甸园空间大约300 x,如果它们没有填满,我会感到惊讶

我想检查一下,您没有创建很多非常短暂的对象,这就是为什么JVM认为几乎没有任何东西能够存活下来的原因


例如,查看是否可以在不创建对象的情况下解析/处理UDP数据包。

当堆和堆栈内存看起来不错时,尝试查找有关“直接内存”的内存泄漏。就我而言,Netty5 ByteBuf的一部分没有发布。

谢谢你的回答。我确信没有“大”数组,该程序构建了一个udp服务器,用于接收和分析包(小于1024字节)。运行3-5天后,会发生这种情况。是否正在使用
ArrayList
StringBuilder
?或者其他一些在场景后面使用数组的数据结构?可能有,但不可能有“大”数组,因为只有在3-5天正常工作后才会发生这种情况(程序每秒接收10-20个小包,每个包都是独立的)。@PeterLawrey-Gixed。Ganks@vzyh-那没必要。例如,如果您的数据结构随着时间积累越来越多的数据,那么可能会有数组的大小在增长。该程序会构建一个udp服务器,用于接收和分析数据包(小于1024字节)。3-5天后,一切正常,这就发生了。我没有设置surviorratio选项,实际大小由JVM决定。我尝试删除“-Xms512M-Xmx512M-XX:PermSize=70M-XX:MaxPermSize=70M”选项,然后将大小更改为1024,直到现在2天工作正常,我将在future@vzyh设置调谐参数通常会产生意外的后果,这可能是由于奇怪的交互作用造成的。注意,除非您的计算机中只有2 GB,否则您将增加堆大小,默认为主内存的1/4。在设置-Xmn512m-XX:SurvivorRatio=8后,开始时似乎没有问题,S0和S1都是40M Eden空间400M,但一天后S0和S0更改为16M,Eden空间更改为480M,因此,当程序运行时,JVM正在调整这些参数。我猜一两天后S0和S1将再次达到512K。使用jprofiler我发现记录器创建了太多的字符[],大约10分钟500米,YGC将清除所有字符,它们将无法在幸存者空间中生存,我猜这就是JVM自动增加伊甸园空间的原因。但我还是没有找到关于频率满gc的任何东西。我找到了!直接内存未正确释放。ByteBuffer jdk(似乎可以用gc清洗)和ByteBuf of Netty5(不能用gc清洗)。