FULL PRODUCT VERSION :
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When G1 GC is in use (-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC), an exception is thrown when trying to access to Last GC info through com.sun.management.GarbageCollectorMXBean.
Test code to reproduce the exception is provided.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just launch the provided test code using "-server -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC"
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: used = 70456352 should be <= committed = 70254592
at java.lang.management.MemoryUsage.<init>(MemoryUsage.java:141)
at sun.management.GcInfoBuilder.getLastGcInfo0(Native Method)
at sun.management.GcInfoBuilder.getLastGcInfo(GcInfoBuilder.java:63)
at sun.management.GarbageCollectorImpl.getLastGcInfo(GarbageCollectorImpl.java:69)
at PrivateGarbageCollectorMXBeanFailure$1.handleNotification(PrivateGarbageCollectorMXBeanFailure.java:35)
at sun.management.NotificationEmitterSupport.sendNotification(NotificationEmitterSupport.java:138)
at sun.management.MemoryImpl.createNotification(MemoryImpl.java:171)
at sun.management.MemoryPoolImpl$CollectionSensor.triggerAction(MemoryPoolImpl.java:300)
at sun.management.Sensor.trigger(Sensor.java:120)
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.util.ArrayList;
import java.util.List;
import javax.management.Notification;
import javax.management.NotificationEmitter;
import javax.management.NotificationListener;
public class PrivateGarbageCollectorMXBeanFailure {
/**
* Exception got if launched with -server -XX:+UnlockExperimentalVMOptions
* -XX:+UseG1GC
*
* @param args
*/
public static void main(String[] args) {
final MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
if (mbean != null) {
NotificationEmitter emitter = (NotificationEmitter) mbean;
emitter.addNotificationListener(new NotificationListener() {
@Override
public void handleNotification(Notification notification,
Object handback) {
for (GarbageCollectorMXBean bean : ManagementFactory
.getGarbageCollectorMXBeans()) {
// This crashes with G1
try {
if (bean instanceof com.sun.management.GarbageCollectorMXBean) {
com.sun.management.GarbageCollectorMXBean sunbean = (com.sun.management.GarbageCollectorMXBean) bean;
System.out.println(sunbean.getLastGcInfo()
.getStartTime());
System.out.println(sunbean.getLastGcInfo()
.getEndTime());
System.out.println(sunbean.getLastGcInfo()
.getDuration());
System.out.println(sunbean.getLastGcInfo()
.getMemoryUsageAfterGc());
System.out.println(sunbean.getLastGcInfo()
.getMemoryUsageBeforeGc());
}
} catch (Throwable t) {
t.printStackTrace();
System.exit(0);
}
}
}
}, null, null);
} else {
}
// enable threshold for all pools
List<MemoryPoolMXBean> mbeansPool = ManagementFactory
.getMemoryPoolMXBeans();
for (int i = 0; i < mbeansPool.size(); i++) {
MemoryPoolMXBean poolBean = (MemoryPoolMXBean) mbeansPool.get(i);
if (poolBean.isValid()
&& poolBean.isCollectionUsageThresholdSupported()) {
poolBean.setCollectionUsageThreshold(1);
}
}
// Allocate 64M of base memory
allocate(64 * 1024 * 1024);
increment(256);
Integer a;
for (int i = 0;; i++) {
a = new Integer(i);
}
}
static ArrayList<byte[]> blocks = new ArrayList<byte[]>();
public static void allocate(long size) {
long kilos = size / 1024L;
long remainder = size % 1024;
blocks.clear();
blocks.ensureCapacity((int) (kilos + 1));
for (int i = 0; i < kilos; i++) {
blocks.add(new byte[1024]);
}
blocks.add(new byte[(int) remainder]);
}
public static void increment(final int rate) {
new Thread() {
public void run() {
for (int i = 0;; i++) {
blocks.add(new byte[rate]);
// if (i%60 ==0) {
// System.gc();
// }
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
---------- END SOURCE ----------
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) Server VM (build 17.0-b16, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
When G1 GC is in use (-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC), an exception is thrown when trying to access to Last GC info through com.sun.management.GarbageCollectorMXBean.
Test code to reproduce the exception is provided.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just launch the provided test code using "-server -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC"
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: used = 70456352 should be <= committed = 70254592
at java.lang.management.MemoryUsage.<init>(MemoryUsage.java:141)
at sun.management.GcInfoBuilder.getLastGcInfo0(Native Method)
at sun.management.GcInfoBuilder.getLastGcInfo(GcInfoBuilder.java:63)
at sun.management.GarbageCollectorImpl.getLastGcInfo(GarbageCollectorImpl.java:69)
at PrivateGarbageCollectorMXBeanFailure$1.handleNotification(PrivateGarbageCollectorMXBeanFailure.java:35)
at sun.management.NotificationEmitterSupport.sendNotification(NotificationEmitterSupport.java:138)
at sun.management.MemoryImpl.createNotification(MemoryImpl.java:171)
at sun.management.MemoryPoolImpl$CollectionSensor.triggerAction(MemoryPoolImpl.java:300)
at sun.management.Sensor.trigger(Sensor.java:120)
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.util.ArrayList;
import java.util.List;
import javax.management.Notification;
import javax.management.NotificationEmitter;
import javax.management.NotificationListener;
public class PrivateGarbageCollectorMXBeanFailure {
/**
* Exception got if launched with -server -XX:+UnlockExperimentalVMOptions
* -XX:+UseG1GC
*
* @param args
*/
public static void main(String[] args) {
final MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
if (mbean != null) {
NotificationEmitter emitter = (NotificationEmitter) mbean;
emitter.addNotificationListener(new NotificationListener() {
@Override
public void handleNotification(Notification notification,
Object handback) {
for (GarbageCollectorMXBean bean : ManagementFactory
.getGarbageCollectorMXBeans()) {
// This crashes with G1
try {
if (bean instanceof com.sun.management.GarbageCollectorMXBean) {
com.sun.management.GarbageCollectorMXBean sunbean = (com.sun.management.GarbageCollectorMXBean) bean;
System.out.println(sunbean.getLastGcInfo()
.getStartTime());
System.out.println(sunbean.getLastGcInfo()
.getEndTime());
System.out.println(sunbean.getLastGcInfo()
.getDuration());
System.out.println(sunbean.getLastGcInfo()
.getMemoryUsageAfterGc());
System.out.println(sunbean.getLastGcInfo()
.getMemoryUsageBeforeGc());
}
} catch (Throwable t) {
t.printStackTrace();
System.exit(0);
}
}
}
}, null, null);
} else {
}
// enable threshold for all pools
List<MemoryPoolMXBean> mbeansPool = ManagementFactory
.getMemoryPoolMXBeans();
for (int i = 0; i < mbeansPool.size(); i++) {
MemoryPoolMXBean poolBean = (MemoryPoolMXBean) mbeansPool.get(i);
if (poolBean.isValid()
&& poolBean.isCollectionUsageThresholdSupported()) {
poolBean.setCollectionUsageThreshold(1);
}
}
// Allocate 64M of base memory
allocate(64 * 1024 * 1024);
increment(256);
Integer a;
for (int i = 0;; i++) {
a = new Integer(i);
}
}
static ArrayList<byte[]> blocks = new ArrayList<byte[]>();
public static void allocate(long size) {
long kilos = size / 1024L;
long remainder = size % 1024;
blocks.clear();
blocks.ensureCapacity((int) (kilos + 1));
for (int i = 0; i < kilos; i++) {
blocks.add(new byte[1024]);
}
blocks.add(new byte[(int) remainder]);
}
public static void increment(final int rate) {
new Thread() {
public void run() {
for (int i = 0;; i++) {
blocks.add(new byte[rate]);
// if (i%60 ==0) {
// System.gc();
// }
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
---------- END SOURCE ----------