我正在使用java应用程序,在分析GC日志时,我可以看到Full GCs的频率在某一时刻有所增加。从日志中我能够理解,在此期间应用程序中存在大量处理,并且大数据没有。线程处于阻塞状态。
在高频完整GC期间,gc日志中显示的堆容量已减少。
发出前的1978609K-> 1567890K(X)
发行期间1778609K-> 1567890K(X-400MB)
发行后1978609K-> 1567890K(X)
即。如果在发布之前容量显示为x,则在发布期间容量减少了400 MB,然后一旦应用程序恢复,容量再次增加。我的问题是,为什么容量减少了?
哪些因素可以动态影响堆容量? 最大和最小堆已配置为X
java版本是1.7.0 Java HotSpot(TM)64位服务器VM 我没有修改自适应策略。因此默认设置存在。
让我更清楚地提出我的问题。我知道GC甚至可以在使用完整堆内存之前发生。但据我所知,下面GC日志中括号中的值应始终保持不变,以显示总可用堆或堆容量。正是这种堆容量变化令我担忧。如果我的理解是错误的,请纠正我。
[Full GC 1778609K->1567890K(total available heap), 1,5589690 secs]
答案 0 :(得分:1)
有各种可能的解释。 (垃圾收集器实现很复杂,在现代JVM中,您会增加复杂性,即收集器的行为不同的种会有不同的行为。)
然而,一种可能的(简单)解释是由对象大小的可变性引起的。
当您的代码尝试分配新对象时,通常会触发垃圾收集,并且没有足够的可用内存可用。如果你的代码试图分配一个大对象,那么它可能会触发垃圾收集早期(即当堆不够满时),而不是它只是试图分配小对象。
因此,“发布期间”日志可能只是导致您的应用程序需要分配一个非常大的对象。例如,您可能需要扩展一个大的,长寿的ArrayList
或HashMap
。或者您可能有一个需要大型临时数组的请求类型。
答案 1 :(得分:0)
你有许多空间,伊甸园,幸存者和终身。当伊甸园空间(可以改变大小)填满时,会触发次要GC。此时使用的数量可能会有所不同,但这并不意味着容量或最大内存已发生变化。
答案 2 :(得分:0)
听起来像自适应尺寸,年轻一代和老一代之间的“边界”可以移动。您没有说明您使用的Java运行时,版本以及GC的配置。试试-XX:-UseAdaptiveSizePolicy
。