即使剩下大量未使用的内存,为什么GC会发生

时间:2017-06-12 21:31:18

标签: java garbage-collection jvm newrelic

enter image description here (承诺和最大行数相同)

我正在查看newrelic中Java应用程序的内存使用情况。以下是几个问题:

#1

committed PS Survivor Space Heap过去几天有所不同。但是它应该是一个常量,因为它是由JVM配置的吗?

#2

根据我的理解,当存在垃圾收集时,堆内存应该减少。当主要gc或次要gc发生时,Eden的内存可能会减少,而当主要gc发生时,Old的内存可能会减少。

但是如果你看看Old内存使用量,在6月6日到7日之间的某个时间,内存会上升然后会下降。这应该代表一个主要的gc发生,对吧?但是,仍有大量未使用的内存。它似乎没有达到极限。然后如何触发主要的gc?对于Eden内存使用情况来说,它从未达到限制但仍然会降低。

应用程序从其他位置获取文件。此文件可能很大并在内存中处理。这可以解释上面的问题吗?

1 个答案:

答案 0 :(得分:2)

您需要提供有关配置的更多信息才能明确回答这个问题,我假设您正在使用Oracle的Hotspot JVM并且您正在使用G1收集器。发布启动JVM的标志也很有用。

  1. 这里的关键术语是'承诺'。这是JVM保留的内存,但不一定在使用(甚至映射到物理页面,它只是JVM可以使用的一系列虚拟内存)。在java.lang.management包的MemoryUsage类中有一个很好的描述(请查看API文档)。它表示,“committed表示保证可供Java虚拟机使用的内存量(以字节为单位)。提交的内存量可能会随着时间的推移而变化(增加或减少).Java虚拟机可能会释放内存到系统......“这就是你看到它改变的原因。

  2. 假设您正在使用G1,那么收集器会执行增量压缩。你是对的,如果收藏家无法跟上老一代的分配,并且它的空间越来越小,它将执行一个完整的压缩集合。这不会发生在这里,因为最后一个图表显示您在分配的堆空间附近没有使用。但是,要避免这种情况,G1会同时收集并压缩您的应用程序。这就是为什么你看到使用率上升(当你的应用程序实例化更多对象时)然后向下(因为G1收集器从不再需要的对象中回收空间)。有关G1如何工作的更详细说明,请仔细阅读文档https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc.html