【发布时间】:2025-12-15 14:30:01
【问题描述】:
我通过使用 ExecutorService 使用 50 个线程在缓存中加载 5000 个对象来测试 Guava 缓存的性能。我想看看缓存对象占用的堆。
看起来缓存对象占用了 25MB。
后来,我在主线程上放了一个 Thread.sleep 让应用程序休眠 10 分钟,这样我就可以对内存等进行采样了。
令人惊讶的是,即使应用程序处于睡眠状态,它也会每 4 分钟产生 20MB 的垃圾。由于每 4 分钟进行一次 GC 操作,因此我在已用堆图中看到了锯齿波。
为什么 java 在空闲应用程序中每分钟会产生 5MB 的垃圾?
更新: 我只运行了一个 main 方法,只调用了 Thread.sleep 10 分钟。
内存分配为每分钟 4 MB。
以下是内存采样器屏幕截图。 看起来只有导致所有活动的 RMI TCP 连接线程。
仅仅是我们观察到的 VisualVM 导致了所有这些活动的事实吗?还是常规的 jvm 活动?
【问题讨论】:
-
主线程休眠时9个守护线程在做什么?
-
更重要的是,最好不要再关心这些细节了。某处某处的某个线程正在运行一些预定的代码或类似的代码,并每秒产生 80 KB 的垃圾。它可能是与 VisualVM 通信的线程。这不会影响您的应用程序的整体行为。
-
ExecutorService 50 个线程于下午 3:28 完成并终止。 JVM 本身有 10 个守护线程。应用程序只有 1 个活动的非守护线程。那一个线程睡了大约 10 分钟。
-
@MarkoTopolnik 我同意你的看法。我可以忽略它,因为它不会产生任何问题。令人惊讶的是,我的 5000 个对象对缓存仅占用 5MB,而 JVM 每分钟产生 5MB 垃圾。
-
保留内存和垃圾之间存在巨大差异。短期对象收集起来非常便宜,许多 Java 习惯用法自然地涉及到此类对象。
标签: java garbage-collection visualvm