FULL PRODUCT VERSION :
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
FULL OS VERSION :
Debian 4.3.0-1-amd64
Microsoft Windows [version 10.0.14393]
A DESCRIPTION OF THE PROBLEM :
When java is started with the options -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent, the collection usage for the largest heap (in this case the MBean with object name java.lang:type=MemoryPool,name=G1 Old Gen) returns always 0.
If only one of this options is set, collection usage returns the expected value.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Compile the Main.java: javac Main.java
2) Run it with and without GC flags:
java -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent Main
java -XX:+UseG1GC Main
java -XX:+ExplicitGCInvokesConcurrent Main
EXPECTED VERSUS ACTUAL BEHAVIOR :
When started with -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent, MemoryPoolMXBean.getCollectionUsage().getUsed() always returns 0 else it returns the expected value.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
root@lanzarote:/tmp# java -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent Main
java.lang:type=MemoryPool,name=G1 Old Gen
Collection usage = 0, usage = 51,765,344
Collection usage = 0, usage = 104,388,048
Collection usage = 0, usage = 156,762,032
Collection usage = 0, usage = 209,167,296
Collection usage = 0, usage = 261,638,432
root@lanzarote:/tmp# java -XX:+UseG1GC Main
java.lang:type=MemoryPool,name=G1 Old Gen
Collection usage = 52,720,512, usage = 52,720,512
Collection usage = 105,256,688, usage = 105,256,688
Collection usage = 157,685,504, usage = 157,685,504
Collection usage = 210,114,320, usage = 210,114,320
Collection usage = 262,543,136, usage = 262,543,136
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void main(String[] args) throws Exception {
MemoryPoolMXBean tenuredGenPool = null;
List<byte[]> data = new ArrayList<>();
// heuristic to find the tenured pool (largest heap) as seen on
// http://www.javaspecialists.eu/archive/Issue092.html
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
if (pool.getType() == MemoryType.HEAP && pool.isUsageThresholdSupported()) {
tenuredGenPool = pool;
}
}
System.out.println(tenuredGenPool.getObjectName());
for (int i = 0; i < 5; i++) {
data.add(new byte[1024 * 1024 * 50]);
Thread.sleep(100);
System.gc();
System.out.println("Collection usage = " + tenuredGenPool.getCollectionUsage().getUsed()
+ ", usage = " + tenuredGenPool.getUsage().getUsed());
}
}
}
---------- END SOURCE ----------