
一种可靠的方法是在GC事件上注册通知侦听器,并在所有Full
GC事件发生后检查内存运行状况。在发生完全GC事件后,直接使用的内存就是您实际的实时数据集。如果此时您的可用内存不足,则可能是时候开始向磁盘移动。
这样,您可以避免在不知道何时发生完整GC的情况下(例如在使用
MEMORY_THRESHOLD_EXCEEDED通知类型时)尝试检查内存时经常发生的误报。
您可以使用以下代码注册通知侦听器并处理Full GC事件:
// ... standard imports ommittedimport com.sun.management.GarbageCollectionNotificationInfo;public static void installGCMonitoring() { List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); for (GarbageCollectorMXBean gcBean : gcBeans) { NotificationEmitter emitter = (NotificationEmitter) gcBean; NotificationListener listener = notificationListener(); emitter.addNotificationListener(listener, null, null); }}private static NotificationListener notificationListener() { return new NotificationListener() { @Override public void handleNotification(Notification notification, Object handback) { if (notification.getType() .equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo .from((CompositeData) notification.getUserData()); String gctype = info.getGcAction(); if (gctype.contains("major")) { // We are only interested in full (major) GCs Map<String, MemoryUsage> mem = info.getGcInfo().getMemoryUsageAfterGc(); for (Entry<String, MemoryUsage> entry : mem.entrySet()) { String memoryPoolName = entry.getKey(); MemoryUsage memdetail = entry.getValue(); long memMax = memdetail.getMax(); long memUsed = memdetail.getUsed(); // Use the memMax/memUsed of the pool you are interested in (probably old gen) // to determine memory health. } } } } };}相信这篇文章是我们最初提出这个想法的。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)