use of com.sun.management.GarbageCollectionNotificationInfo in project jdk8u_jdk by JetBrains.
the class GarbageCollectionNotificationContentTest method main.
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
final Boolean isNotificationSupported = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
try {
Class cl = Class.forName("sun.management.VMManagementImpl");
Field f = cl.getDeclaredField("gcNotificationSupport");
f.setAccessible(true);
return f.getBoolean(null);
} catch (ClassNotFoundException e) {
return false;
} catch (NoSuchFieldException e) {
return false;
} catch (IllegalAccessException e) {
return false;
}
}
});
if (!isNotificationSupported) {
System.out.println("GC Notification not supported by the JVM, test skipped");
return;
}
final ObjectName gcMXBeanPattern = new ObjectName("java.lang:type=GarbageCollector,*");
Set<ObjectName> names = mbs.queryNames(gcMXBeanPattern, null);
if (names.isEmpty())
throw new Exception("Test incorrect: no GC MXBeans");
number = names.size();
for (ObjectName n : names) {
if (mbs.isInstanceOf(n, "javax.management.NotificationEmitter")) {
listenerInvoked.put(n.getCanonicalName(), null);
GcListener listener = new GcListener();
mbs.addNotificationListener(n, listener, null, null);
}
}
// Invocation of System.gc() to trigger major GC
System.gc();
// Allocation of many short living and small objects to trigger minor GC
Object[] data = new Object[32];
for (int i = 0; i < 100000000; i++) {
data[i % 32] = new int[8];
}
int wakeup = 0;
synchronized (synchronizer) {
while (count != number) {
synchronizer.wait(10000);
wakeup++;
if (wakeup > 10)
break;
}
}
for (GarbageCollectionNotificationInfo notif : listenerInvoked.values()) {
checkGarbageCollectionNotificationInfoContent(notif);
}
System.out.println("Test passed");
}
use of com.sun.management.GarbageCollectionNotificationInfo in project jdk8u_jdk by JetBrains.
the class GarbageCollectorImpl method createGCNotification.
void createGCNotification(long timestamp, String gcName, String gcAction, String gcCause, GcInfo gcInfo) {
if (!hasListeners()) {
return;
}
Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, getObjectName(), getNextSeqNumber(), timestamp, gcName);
GarbageCollectionNotificationInfo info = new GarbageCollectionNotificationInfo(gcName, gcAction, gcCause, gcInfo);
CompositeData cd = GarbageCollectionNotifInfoCompositeData.toCompositeData(info);
notif.setUserData(cd);
sendNotification(notif);
}
use of com.sun.management.GarbageCollectionNotificationInfo in project cassandra by apache.
the class GCInspector method handleNotification.
public void handleNotification(final Notification notification, final Object handback) {
String type = notification.getType();
if (type.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
// retrieve the garbage collection notification information
CompositeData cd = (CompositeData) notification.getUserData();
GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
String gcName = info.getGcName();
GcInfo gcInfo = info.getGcInfo();
long duration = gcInfo.getDuration();
/*
* The duration supplied in the notification info includes more than just
* application stopped time for concurrent GCs. Try and do a better job coming up with a good stopped time
* value by asking for and tracking cumulative time spent blocked in GC.
*/
GCState gcState = gcStates.get(gcName);
if (gcState.assumeGCIsPartiallyConcurrent) {
long previousTotal = gcState.lastGcTotalDuration;
long total = gcState.gcBean.getCollectionTime();
gcState.lastGcTotalDuration = total;
// may be zero for a really fast collection
duration = total - previousTotal;
}
StringBuilder sb = new StringBuilder();
sb.append(info.getGcName()).append(" GC in ").append(duration).append("ms. ");
long bytes = 0;
Map<String, MemoryUsage> beforeMemoryUsage = gcInfo.getMemoryUsageBeforeGc();
Map<String, MemoryUsage> afterMemoryUsage = gcInfo.getMemoryUsageAfterGc();
for (String key : gcState.keys(info)) {
MemoryUsage before = beforeMemoryUsage.get(key);
MemoryUsage after = afterMemoryUsage.get(key);
if (after != null && after.getUsed() != before.getUsed()) {
sb.append(key).append(": ").append(before.getUsed());
sb.append(" -> ");
sb.append(after.getUsed());
if (!key.equals(gcState.keys[gcState.keys.length - 1]))
sb.append("; ");
bytes += before.getUsed() - after.getUsed();
}
}
while (true) {
State prev = state.get();
if (state.compareAndSet(prev, new State(duration, bytes, prev)))
break;
}
String st = sb.toString();
if (GC_WARN_THRESHOLD_IN_MS != 0 && duration > GC_WARN_THRESHOLD_IN_MS)
logger.warn(st);
else if (duration > MIN_LOG_DURATION)
logger.info(st);
else if (logger.isTraceEnabled())
logger.trace(st);
if (duration > STAT_THRESHOLD)
StatusLogger.log();
// if we just finished an old gen collection and we're still using a lot of memory, try to reduce the pressure
if (gcState.assumeGCIsOldGen)
LifecycleTransaction.rescheduleFailedDeletions();
}
}
use of com.sun.management.GarbageCollectionNotificationInfo in project bazel by bazelbuild.
the class RetainedHeapLimiter method handleNotification.
@Override
public void handleNotification(Notification notification, Object handback) {
if (!notification.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
return;
}
GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
Map<String, MemoryUsage> spaces = info.getGcInfo().getMemoryUsageAfterGc();
for (Map.Entry<String, MemoryUsage> entry : spaces.entrySet()) {
if (isTenuredSpace(entry.getKey())) {
MemoryUsage space = entry.getValue();
if (space.getMax() == 0) {
// The CMS collector sometimes passes us nonsense stats.
continue;
}
long percentUsed = 100 * space.getUsed() / space.getMax();
if (percentUsed > occupiedHeapPercentageThreshold) {
if (info.getGcCause().equals("System.gc()") && !throwingOom.getAndSet(true)) {
// Assume we got here from a GC initiated by the other branch.
String exitMsg = String.format("RetainedHeapLimiter forcing exit due to GC thrashing: tenured space " + "%s out of %s (>%s%%) occupied after back-to-back full GCs", space.getUsed(), space.getMax(), occupiedHeapPercentageThreshold);
System.err.println(exitMsg);
LOG.info(exitMsg);
// Exits the runtime.
BugReport.handleCrash(new OutOfMemoryError(exitMsg));
} else if (System.currentTimeMillis() - lastTriggeredGcInMilliseconds > MIN_TIME_BETWEEN_TRIGGERED_GC_MILLISECONDS) {
LOG.info("Triggering a full GC with " + space.getUsed() + " out of " + space.getMax() + " used");
// Force a full stop-the-world GC and see if it can get us below the threshold.
System.gc();
lastTriggeredGcInMilliseconds = System.currentTimeMillis();
}
}
}
}
}
Aggregations