Java 终身生成垃圾回收未清除

Java 终身生成垃圾回收未清除,java,spring,multithreading,spring-boot,garbage-collection,Java,Spring,Multithreading,Spring Boot,Garbage Collection,我有一个JavaSpring启动项目。在内存中执行与多线程(执行器服务)相关的代码时 正在被填满。GC未清除此内存。在阅读了GC文档之后,我知道永久内存没有被清除。 通过使用Java Profiler监视JVM,我注意到这一长期生成永远不会被清除(对于我来说,直到完全清除) 我怎样才能让gc清理终身空间 我们使用docker image运行应用程序这里有两个潜在问题 垃圾收集器只能释放无法访问的对象。因此,如果永久对象仍然可以访问,它们将永远不会被释放。这是一个内存泄漏场景 JVM可能没有运行

我有一个JavaSpring启动项目。在内存中执行与多线程(执行器服务)相关的代码时 正在被填满。GC未清除此内存。在阅读了GC文档之后,我知道永久内存没有被清除。 通过使用Java Profiler监视JVM,我注意到这一长期生成永远不会被清除(对于我来说,直到完全清除)

  • 我怎样才能让gc清理终身空间

  • 我们使用docker image运行应用程序

    这里有两个潜在问题

  • 垃圾收集器只能释放无法访问的对象。因此,如果永久对象仍然可以访问,它们将永远不会被释放。这是一个内存泄漏场景

  • JVM可能没有运行旧的/永久的空间集合,因为它不需要这样做。JVM通常只在认为有必要/经济的情况下运行旧的空间收集器。这实际上是一件好事,因为大多数容易(便宜)收集的垃圾通常都在新的空间中


  • 在阅读了gc文档之后,我知道永久内存没有被清除

    这可能是对文档的误读。GC将收集永久空间中的对象。这应该在你开始吐之前发生


    我如何让总承包商清理终身空间

    您可以调用
    System.gc()
    。。。这给JVM一个提示,现在运行GC将是一件好事。然而:

    • 这只是一个暗示。JVM可能会忽略它
    • 它可能运行也可能不运行旧的空间集合
    • 它不会“清除”老一代。它甚至不一定会释放所有无法访问的对象
    • 调用
      System.gc()
      通常效率低下。JVM通常更了解运行GC的最有效时间,以及运行哪种GC
    • 运行GC实际上可能不会释放内存供系统的其余部分使用

    简言之,调用
    System.gc()
    可能是一个坏主意。在大多数情况下,它不会取得任何成果


    如果您真正的问题是内存泄漏,那么它肯定会有所帮助。如果你得到的是OOME,那就没用了。

    对于1500条记录,它占用了80%的CPU。这也是内存泄漏吗?内存为4GB。我们使用ExecutorService添加了线程(50个),假设对于较大的文件,它需要更长的时间才能完成。这里在一定的时间段中,中间内存溢出堆空间。尝试了不同的GC选项仍然没有解决,这是不可能说的。如果你怀疑内存泄漏,你应该搜索Q&a等关于如何诊断、发现和修复内存泄漏的问题。(尝试不同的GC选项并不能解决内存泄漏问题。根本问题在于应用程序代码……某个地方。)另一种可能性是,通过在50个并行线程上投入大量工作,可能会增加内存需求,导致堆太小。将其与真正的内存泄漏区分开来有点棘手。谢谢你的澄清。在代码级别识别内存泄漏的可能方法有哪些?堆转储会有帮助吗?是的。我不明白你说的“1500条记录占用了80%的CPU”是什么意思。(什么是“it”?)但高CPU利用率并不是内存泄漏的明确迹象。也读。。。我们使用ExecutorService添加了线程(50个),假设较大的文件需要较长的时间才能完成。这里在一定的时间段中,中间内存溢出堆空间。尝试使用不同的GC选项仍然没有解决问题。您没有解释为什么您认为永久内存是问题所在。启动JVM时设置
    -XX:HeapDumpOnOutOfMemoryError
    选项,并在获得OOME时查看内存中的对象。@tgdavies我正在docker中运行应用程序。所以我可以使用Spring boot Acurator进行堆转储吗?这会有帮助吗?我没有使用执行器,但是heapdump端点应该为您提供一个,是的。