为什么堆内存使用量和装入类的数量不断增加?

2022-09-04 22:20:37

我正在使用 - 链接到JVM资源管理器,以分析我的Spring应用程序。我有以下问题。JVM Explorer

  • 为什么“已用堆内存”即使在应用程序启动并且尚未收到任何请求后仍会不断增加?(图1)

  • 为什么即使在垃圾回收之后,在收到任何请求之前,“已用堆内存”也在不断增加?(图2)

  • 为什么在垃圾回收之后,通过向应用程序发送一些请求,加载类的数量正在增加?应用程序不应该使用以前的类吗?为什么它只是增加几乎所有东西(堆,加载的类的数量)?(图3)

    应用程序启动后 - 放大图像 enter image description here

    点击“运行垃圾回收器”按钮后。- 放大图像

enter image description here

在垃圾回收程序完成后向应用程序发送一些请求后 - 放大图像

enter image description here


答案 1

为什么“已用堆内存”即使在应用程序启动并且尚未收到任何请求后仍会不断增加?(图1)

JVM 中的某些内容正在创建对象。您需要一个内存探查器来查看正在执行此操作的原因。它可以是Swing的一部分,或者yoru应用程序或其他库的一部分。

顺便说一句,大多数分析工具都使用JMX来处理大量垃圾。例如,当我在我的一些应用程序上运行FlightRecorder或VisualVM时,它显示JMX监控正在创建大部分垃圾。

为什么即使在垃圾回收之后,在收到任何请求之前,“已用堆内存”也在不断增加?(图2)

无论创建对象的是什么,仍然在创建对象。

为什么在垃圾回收之后,通过向应用程序发送一些请求,加载类的数量正在增加?

类被懒惰地加载。有些类在你做某事之前是不需要的。

应用程序不应该使用以前的类吗?

是的,但这并不意味着它不需要更多的类。

为什么它只是增加几乎所有东西(堆,加载的类的数量)?(图3)

您的应用程序正在执行更多工作。

如果您想知道应用程序正在执行哪些工作,我建议使用VisualVM或Flight Recorder等内存分析器。我使用YourKit来回答这类问题。

注意:调整Java程序需要付出艰苦的努力,这样它就不会产生垃圾,我会说大多数库只有在导致已知性能问题时才会尝试减少垃圾。


答案 2

我喜欢@PeterLawrey的好答案,但是那里缺少这个:

内存主要用于使用而不是备用。您的应用程序可能很容易写得很好:它可以使用小内存工作,并且可以重新创建所需的所有内存,但它也可以有效地利用系统具有大量内存的事实,并且应用程序使用所有可能的内存来更有效地工作。

我可以很容易地想象,不断占用内存的东西就是缓存。如果缓存包含大量数据,则应用程序的工作速度会更快。

如果您没有像您这样的问题,则不必担心。你仍然应该保持警惕并进一步检查它,但你所描述的情况并不自动意味着出了什么问题。OutOfMemoryError

这类似于Windows用户不断哀叹“我买了更多的内存,但我的Windows用完了它” - 当内存被使用时,这很好!这就是我们购买它的目的!


推荐