为什么堆内存使用量和加载类的数量不断增加?
我正在使用JVM Explorer
– 链接到JVM资源管理器 ,以分析我的Spring应用程序。 我有以下问题。
-
为什么即使在应用程序启动并且尚未收到任何请求后,“使用堆内存”仍在不断增加? (图1)
-
为什么即使在垃圾收集之后和收到任何请求之前’使用堆内存’仍在不断增加? (图像2)
-
为什么在垃圾收集之后,通过向应用程序发送一些请求来加载类的数量正在增加? 应用程序不应该使用以前的类吗? 为什么它只是增加几乎所有东西(堆,加载类的数量)? (图像3)
应用程序启动后 – 放大图像
单击“运行垃圾收集器”按钮后。 – 放大图像
在完成垃圾收集程序后向应用程序发送一些请求后 – 放大图像
为什么即使在应用程序启动并且尚未收到任何请求后,“使用堆内存”仍在不断增加? (图1)
JVM中的某些东西正在创建对象。 你需要一个内存分析器来看看这是做什么的。 它可能是Swing,或yoru应用程序或其他库的一部分。
BTW大多数分析工具使用JMX处理大量垃圾。 例如,当我在某些应用程序上运行FlightRecorder或VisualVM时,它显示JMX监视正在创建大部分垃圾。
为什么即使在垃圾收集之后和收到任何请求之前’使用堆内存’仍在不断增加? (图像2)
无论创建对象是什么,仍然在创建对象。
为什么在垃圾收集之后,通过向应用程序发送一些请求来加载类的数量正在增加?
类是懒惰加载的。 在你做某事之前,不需要一些课程。
应用程序不应该使用以前的类吗?
是的,但这并不意味着它不需要更多的课程。
为什么它只是增加几乎所有东西(堆,加载类的数量)? (图像3)
您的应用程序正在做更多工作。
如果你不知道应用程序正在做什么工作,我建议使用像VisualVM或Flight Recorder这样的内存分析器。 我使用YourKit来解决这些问题。
注意:调整Java程序需要付出艰苦的努力,这样才不会产生垃圾。我想说大多数库只会在导致已知性能问题的情况下尝试减少垃圾。
我喜欢@PeterLawrey的好答案,但是那里缺少:
内存主要用于使用 ,而不是保留 。 可能很容易就是你的应用程序写得很好:它可以使用一个小内存,它可以重新创建它所需要的一切,但它也可以有效地利用你的系统有大量内存和应用程序的事实使用所有可能的内存来更有效地工作。
我可以很容易地想象,不断占用内存的东西就是缓存 。 如果缓存包含大量数据,则应用程序的运行速度更快。
如果您没有像OutOfMemoryError
这样的问题,则无需担心。 你应该保持警惕并进一步检查,但你所描述的情况并不会自动意味着出现了问题。
它类似于Windows用户的不断哀悼,“我已经购买了更多的内存但我的Windows全部使用了” – 使用内存时效果很好! 这就是我们买的!