Java 奇数堆使用模式

Java 奇数堆使用模式,java,heap,visualvm,Java,Heap,Visualvm,我有一个重复的过程: 从数据库中获取一些数据 在内存中生成一些对象,并将其添加到集合中 将集合中的数据写入文件 每次迭代后,所有对象/集合都超出范围或设置为null。(集合将在每次迭代中重复使用。) 使用JavaVisualVM,我看到一个类似这样的图,考虑到它是一个重复的过程,这看起来很奇怪。是的,从数据库返回的数据是不同的,但通常是相同的数量 为什么堆大小一开始会减小? 为什么使用的堆在中间的堆大小如此接近? (1:43的~30秒光点正好是VisualVM瞬间冻结的时候)我并不像某些人那样

我有一个重复的过程:

  • 从数据库中获取一些数据
  • 在内存中生成一些对象,并将其添加到集合中
  • 将集合中的数据写入文件
  • 每次迭代后,所有对象/集合都超出范围或设置为null。(集合将在每次迭代中重复使用。)

    使用JavaVisualVM,我看到一个类似这样的图,考虑到它是一个重复的过程,这看起来很奇怪。是的,从数据库返回的数据是不同的,但通常是相同的数量

    为什么堆大小一开始会减小? 为什么使用的堆在中间的堆大小如此接近?
    (1:43的~30秒光点正好是VisualVM瞬间冻结的时候)

    我并不像某些人那样是GC方面的专家,但一般的想法是,当你启动程序时,你已经给了它初始堆大小、最大堆大小和其他相关参数,然后它就开始运行了

    然而,GC拥有大量的智能和针对不同类型任务优化的不同算法。一个简单的实现只是保持堆大小不变,然后在垃圾满时收集垃圾。这被称为“停止世界”收集,因为收集者需要停止一切,以便能够执行小(或大)清理

    现代GC不只是因为需要清理而在运行程序时造成长时间暂停,所以从锯齿图上看,总是有一些清理在进行。但是当您启动一个程序时,GC不知道该程序将要做什么以及它将如何使用内存。因此,它必须观察正在发生的事情,分析内存使用情况,然后决定需要保留多少内存以供立即使用,是需要增加当前堆大小,还是可以减少当前堆大小


    根据程序的行为和使用的GC算法,您可以看到许多不同的模式。只要您没有经历最终导致
    OutOfMemoryError
    的线性增长,您就应该相对安全。当然,除非您想优化正在发生的事情,以提高吞吐量、响应能力等,但这是一个更高级的主题,而且当您的代码按照您想要的方式工作时,它更相关。

    您使用的是哪种GC?无论Java 1.8.071、Tomcat 7.0.54中的默认GC是什么,RHEL 7.2这是一种重复模式吗?@MordechayS-不,似乎只有在JVM重新启动后才会发生这种情况。@Matt这对你来说有什么奇怪的地方?GC并不愚蠢。如果你正在做一个重复的过程,那么GC将学习它,并且变得非常重复。你看到的是GC“测试水”的开始。大概在10分钟后观察内存使用情况,你会看到一个规则的锯齿模式。