了解GC:分配失败并使用临时String对象填充OldGen

问题描述 投票:-1回答:1

我跟进了几个好问题和他们的答案,但我仍有疑问。

这是我理解的,并且希望看到理解是否正确。

无论何时在YoungGen上分配新内存,GC(分配失败)都会启动。

此外,根据对象的大小,可能必须将某些对象推送到OldGen,并且可以将更大的对象直接移动到OldGen。

应用程序行为:“分配失败”的原因是创建了大量字符串。在使用JFR和HeapDump进一步调试时,所有内容都指向很多char []和String对象,这些对象是在我们的系统中临时创建的(即YoungGen候选者)。其中一些字符串确实很大(每个约25KB)。虽然,根据错误消息,YoungGen中有足够的可用空间,而Heap甚至可能无法接近最大内存。

在同一时间,OldGen正在增加,即使在完全GC之后也没有得到清理。可能会有另一个内存泄漏,但没有任何指向这一点。所以,我不明白为什么即使在完整的GC之后OldGen仍保持在同一水平。

除了验证我的理解之外,问题是:可以创建大量临时String / char []对象(通过strA + strB,new String()/ StringBuilder()。toString(),String.split() ,String.substring(),Stream-> buffer conversion等)即使应用程序在YoungGen和堆中有大量可用内存,GC也会非常频繁地运行?如果是,何时以及有哪些替代方案?

谢谢!

java garbage-collection jvm heap-memory heap-dump
1个回答
0
投票

我会说答案是有条件的。

请记住,年轻人分为3个部分,即伊甸园,S0和S1,这意味着你没有像你想象的那样拥有年轻人的记忆。如果你溢出其中一个幸存者空间,其余的将被推到旧的(过早的促销),填补旧的gen。另请注意,从年轻人到老年人的晋升是基于gc周期的数量。如果你经常年轻的gen gc将那些应该是短命的对象移到旧的gen(因为你还没有完成temp对象),那么你将填满旧的gen。另请注意,仅仅因为您执行完整的gc,无法保证您实际上会获得任何内存。因此,使用像censum这样的工具来分析您的gc日志,特别是过早推广。可能你必须调整年轻的gen / old比率。

© www.soinside.com 2019 - 2024. All rights reserved.