2015-01-02 18 views
0

我正在使用ExecutorService使用50个线程加载5000个缓存对象来测试Guava缓存的性能。我想看看被缓存的对象占用的堆。为什么闲置的Java应用程序在4分钟内生成20 MB垃圾?

它看起来好像缓存的对象吃了25MB。

后来,我把了Thread.sleep在主线程睡眠应用10分钟,这样我就可以品尝内存等

出人意料的是,即使在应用程序处于睡眠,它产生20MB的垃圾每4分钟一次。由于每4分钟有一次GC操作,因此在使用的堆图中会看到一个锯齿波。 enter image description here

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

UPDATE: 我跑了一个主要方法,只需要调用Thread.sleep 10分钟。

内存分配是每分钟4 MB。 enter image description here

下面是内存采样器截图。 看起来只是引起所有活动的RMI TCP连接线程。 enter image description here

这只是事实,我们正在观察与VisualVM导致所有的活动?或者它是常规的jvm活动?

+1

当主线程睡着时,9个守护进程线程在做什么? –

+1

更重要的是,最好不要关心这些细节。有些线程在某处运行一些预定的代码或类似代码,并且每秒创建80 KB垃圾。它可能是与VisualVM通信的线程。这对你的应用程序的整体行为没有影响。 –

+0

ExecutorService 50个线程在3:28 pm完成并被终止。 JVM本身有10个守护进程线程。应用程序只有1个活动的非守护线程。那一条线睡着了〜10分钟。 – Teddy

回答

0

作为底线:没有人可以回答这样的问题,而无需分析您的应用程序。你需要的是在可视VM中获取内存快照,并检查哪些类正在占用大量内存。此外,它有助于对对象计数进行排序,并查看在GC之前和之后哪些对象的实例数变化最大。

对于快速的glimipse,由于您的图片中显示了11个线程,因此至少您将Runnable对象的节点对象提交到您的ExecutorService,大多数当前的Java库和包会选择此对象。

+0

我的执行者服务在下午3点28分完成并终止了所有50个线程。这是一个测试应用程序...没有其他处理正在完成。可能只有一个应用程序线程处于睡眠状态10分钟,并且有一些由JVM启动的10个守护程序线程。 – Teddy

+0

@Teddy没有人可以回答你没有分析,只能自己做... –

+0

我跑内存采样器,并附上截图 – Teddy

0

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

4 MiB每分钟听起来是合理的数量责怪VisualVM的。

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

相关问题