为什么空闲Java应用程序在4分钟内生成20MB垃圾?

为什么空闲Java应用程序在4分钟内生成20MB垃圾?,java,garbage-collection,visualvm,Java,Garbage Collection,Visualvm,我正在测试Guava缓存的性能,通过使用ExecutorService在缓存中加载5000个对象,使用50个线程。我想看到缓存对象占用的堆 看起来缓存的对象占用了25MB的内存 后来,我在主线程上放置了一个Thread.sleep,使应用程序休眠10分钟,以便对内存等进行采样 令人惊讶的是,即使应用程序处于睡眠状态,它也会每4分钟生成20MB的垃圾。由于每4分钟有一次GC操作,我在使用的堆图中看到一个锯齿波。 为什么java在空闲应用程序中每分钟产生5MB的垃圾 更新: 我只运行了一个main

我正在测试Guava缓存的性能,通过使用ExecutorService在缓存中加载5000个对象,使用50个线程。我想看到缓存对象占用的堆

看起来缓存的对象占用了25MB的内存

后来,我在主线程上放置了一个Thread.sleep,使应用程序休眠10分钟,以便对内存等进行采样

令人惊讶的是,即使应用程序处于睡眠状态,它也会每4分钟生成20MB的垃圾。由于每4分钟有一次GC操作,我在使用的堆图中看到一个锯齿波。

为什么java在空闲应用程序中每分钟产生5MB的垃圾

更新: 我只运行了一个main方法,只调用了Thread.sleep 10分钟

内存分配为每分钟4 MB。

下面是内存采样器屏幕截图。 看起来只有导致所有活动的RMI TCP连接线程。


这仅仅是我们用VisualVM观察的事实导致了所有这些活动吗?或者它是常规的jvm活动?

作为底线:没有人能够在不分析应用程序的情况下回答这样的问题。您需要的是在VisualVM中创建一个内存快照,并检查哪些类占用了大量内存。它还有助于对对象计数进行排序,并查看在GC前后哪些对象的实例计数变化最多


快速浏览一下,因为您的pic中显示了11个线程,所以至少您有提交给ExecutorService的可运行对象的节点对象,当前大多数Java lib和packges都会选择这些对象。

您使用VisualVM来监视您的应用程序。VisualVM正在使用JMX/MBeans获取监控信息。JMX使用RMI作为传输层。VisualVM定期轮询MBean,这转化为通过RMI调用JVM上运行的服务

每分钟4个MiB听起来是VisualVM的合理数字


我建议您使用命令监视您的进程。它显示每个线程的内存分配率,因此您可以验证是否所有垃圾都可以归因于RMI线程,或者您的任何应用程序线程是否乱扔垃圾。

当主线程处于睡眠状态时,9个守护进程线程在做什么?更重要的是,最好不要再关心这些细节。某个线程在某个地方运行某些调度代码或类似代码,每秒产生80KB的垃圾。它可能就是与VisualVM通信的线程。这对应用程序的整体行为没有影响。ExecutorService 50个线程在下午3:28完成并被终止。JVM本身有10个守护进程线程。应用程序只有1个活动的非守护进程线程。那一根线已经睡了大约10分钟。@MarkoTopolnik我同意你的看法。我可以忽略它,因为它不会产生任何问题。令人惊讶的是,我的5000对象对缓存只占用5MB,而JVM每分钟产生5MB的垃圾。保留内存和垃圾之间有着巨大的区别。短生命期的对象收集起来非常便宜,许多Java习惯用法自然涉及到这些对象。我的executor服务在下午3:28完成并终止了所有50个线程。这是一个测试应用程序。。。没有其他正在进行的处理。只有一个应用程序线程处于睡眠状态10分钟,JVM可能启动了大约10个守护进程线程。@Teddy没有人可以回答您,除非进行分析,这只能由您自己完成…我运行了内存采样器并附加了screenshot@Teddy-随附的屏幕截图回答了您的问题。