はい、JVMは、このような情報を取得するのに十分なツールを提供します。たとえば、あなたは、ガベージコレクションに関するすべての詳細を印刷し、このクラス(ただMemoryUtil.startGCMonitor()
を呼び出す)のようなものを使用することができます
public class MemoryUtil {
private static final Set<String> heapRegions;
static {
heapRegions = ManagementFactory.getMemoryPoolMXBeans().stream()
.filter(b -> b.getType() == MemoryType.HEAP)
.map(MemoryPoolMXBean::getName)
.collect(Collectors.toSet());
}
private static NotificationListener gcHandler = (notification, handback) -> {
if (notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
GarbageCollectionNotificationInfo gcInfo = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
Map<String, MemoryUsage> memBefore = gcInfo.getGcInfo().getMemoryUsageBeforeGc();
Map<String, MemoryUsage> memAfter = gcInfo.getGcInfo().getMemoryUsageAfterGc();
StringBuilder sb = new StringBuilder(250);
sb.append("[").append(gcInfo.getGcAction()).append("/").append(gcInfo.getGcCause())
.append("/").append(gcInfo.getGcName()).append("/(");
appendMemUsage(sb, memBefore);
sb.append(") -> (");
appendMemUsage(sb, memAfter);
sb.append("), ").append(gcInfo.getGcInfo().getDuration()).append(" ms]");
System.out.println(sb.toString());
}
};
public static void startGCMonitor() {
for(GarbageCollectorMXBean mBean: ManagementFactory.getGarbageCollectorMXBeans()) {
((NotificationEmitter) mBean).addNotificationListener(gcHandler, null, null);
}
}
public static void stopGCMonitor() {
for(GarbageCollectorMXBean mBean: ManagementFactory.getGarbageCollectorMXBeans()) {
try {
((NotificationEmitter) mBean).removeNotificationListener(gcHandler);
} catch(ListenerNotFoundException e) {
// Do nothing
}
}
}
private static void appendMemUsage(StringBuilder sb, Map<String, MemoryUsage> memUsage) {
memUsage.entrySet().forEach((entry) -> {
if (heapRegions.contains(entry.getKey())) {
sb.append(entry.getKey()).append(" used=").append(entry.getValue().getUsed() >> 10).append("K; ");
}
});
}
}
をこのコードでは、gcInfo.getGcAction()
はあなたに混合/主要なものからマイナーコレクションを分離するのに十分な情報を提供します。
しかし、G1へのアプローチ(しきい値付き)を使用する際には重要な注意点があります。 G1の単一の混合コレクションは、通常、いくつかの古いgenリージョンにのみ影響します。GCのポーズを低く抑えるには、十分な量のメモリを解放するには十分なものが多く、あまり多くはありません。だから、G1の混合コレクションの後に、あなたのゴミがすべて消えてしまったと確信することはできません。結果として、メモリリークを検出するより洗練された戦略を見つける必要があります(コレクションの頻度に基づいて、複数のコレクションから統計を収集するなど)
これは同様の情報を提供する必要があります:http://stackoverflow.com/a/ 32509813/1362755 – the8472