java - 执行Java垃圾回收,但没有收到GC通知
问题描述
我遵循了来自各种来源的一些示例,并具有以下代码段:
private void registerForMemUsageChanges() {
List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMXBeans) {
listenForGarbageCollectionOn(garbageCollectorMXBean);
}
}
private void listenForGarbageCollectionOn(GarbageCollectorMXBean garbageCollectorMXBean) {
NotificationEmitter notificationEmitter = (NotificationEmitter) garbageCollectorMXBean;
GarbageListener listener = new GarbageListener();
notificationEmitter.addNotificationListener(listener, null, null);
}
public class GarbageListener implements NotificationListener {
@Override
public void handleNotification(Notification notification, Object handback) {
if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
doSomthing();//irrelevant
}
}
}
我添加了一个执行以下操作的测试(同样,基于我找到的示例),它似乎有效:
private void triggerGc() throws InterruptedException {
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get() != null) {
System.gc();
}
}
在调试模式下运行时,我看到侦听器已注册到 ps markweep 和 ps scavenge。while 循环完成(我认为这是执行 GC 的标志),但没有调用任何通知。不是 GC 通知或任何类型。
是监听器注册错误还是没有真正执行GC的问题?在 while 循环之后,弱 ref 似乎确实是空的。
我正在使用 openjdk 1.8.0_144。
解决方案
问题实际上是:A)正如 Holger 在评论中提到的,我只收到影响老一代的 GC 通知,并且 B)调试器没有在我的断点处停止,尽管代码已执行,所以即使我不能不知道,doSomething 确实做了一些事情。
推荐阅读
- javascript - 使用 ScrollWatch.js 在现场无限滚动
- python - 使用 matplot 的熊猫在 x 轴日期上显示不正确的年份
- php - 将数据插入共享外键的表中
- c# - 在 C# 上使用 EPP 插入现有的 excel 文件
- c# - 从 json C# 中提取数据
- r - 使用 gsub 将弯撇号和引号替换为直撇号和引号
- node.js - 将角度构建“dist”文件添加到节点 js server.js
- java - 如何将 2D 数组从 CSV 文件导入 JTable
- python-3.x - Pandas Dataframe:我想在划分列时使用 round(),但出现错误
- jenkins - ssh连接主机失败:主机密钥验证失败