8170737: Not enough old space utilisation

Reviewed-by: dfazunen, tschatzl
This commit is contained in:
Michail Chernov 2017-02-03 15:45:57 +03:00
parent 26a978276c
commit 00f485cdfa
11 changed files with 266 additions and 319 deletions

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.management.ManagementFactory;
import utils.GarbageProducer;
import common.TmTool;
import utils.JstatResults;
/**
* Base class for jstat testing which uses GarbageProducer to allocate garbage.
*/
public class GarbageProducerTest {
// Iterations of measurement to get consistent value of counters and jstat.
private final static int ITERATIONS = 10;
private final static float TARGET_MEMORY_USAGE = 0.7f;
private final static float MEASUREMENT_TOLERANCE = 0.05f;
private final GarbageProducer garbageProducer;
private final TmTool<? extends JstatResults> jstatTool;
public GarbageProducerTest(TmTool<? extends JstatResults> tool) {
garbageProducer = new GarbageProducer(TARGET_MEMORY_USAGE);
// We will be running jstat tool
jstatTool = tool;
}
public void run() throws Exception {
// Run once and get the results asserting that they are reasonable
JstatResults measurement1 = jstatTool.measure();
measurement1.assertConsistency();
// Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable
System.gc();
garbageProducer.allocateMetaspaceAndHeap();
// Collect garbage. Also update VM statistics
System.gc();
int i = 0;
long collectionCountBefore = getCollectionCount();
JstatResults measurement2 = jstatTool.measure();
do {
System.out.println("Measurement #" + i);
long currentCounter = getCollectionCount();
// Check if GC cycle occured during measurement
if (currentCounter == collectionCountBefore) {
measurement2.assertConsistency();
checkOldGenMeasurement(measurement2);
return;
} else {
System.out.println("GC happened during measurement.");
}
collectionCountBefore = getCollectionCount();
measurement2 = jstatTool.measure();
} while (i++ < ITERATIONS);
// Checking will be performed without consistency guarantee.
checkOldGenMeasurement(measurement2);
}
private void checkOldGenMeasurement(JstatResults measurement2) {
float oldGenAllocationRatio = garbageProducer.getOldGenAllocationRatio() - MEASUREMENT_TOLERANCE;
// Assert that space has been utilized accordingly
JstatResults.assertSpaceUtilization(measurement2, TARGET_MEMORY_USAGE, oldGenAllocationRatio);
}
private static long getCollectionCount() {
return ManagementFactory.getGarbageCollectorMXBeans().stream()
.mapToLong(b -> b.getCollectionCount())
.sum();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,39 +25,19 @@
* @test
* @summary Test checks output displayed with jstat -gccause.
* Test scenario:
* tests forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show that ~70% of heap (OC/OU ~= 70%).
* test forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show actual usage of old gen (OC/OU ~= old gen usage).
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
* @run main/othervm -XX:+UsePerfData -XX:InitialHeapSize=128M -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcCauseTest02
* @run main/othervm -XX:+UsePerfData -XX:MaxNewSize=4m -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcCauseTest02
*/
import utils.*;
public class GcCauseTest02 {
private final static float targetMemoryUsagePercent = 0.7f;
public static void main(String[] args) throws Exception {
// We will be running "jstat -gc" tool
JstatGcCauseTool jstatGcTool = new JstatGcCauseTool(ProcessHandle.current().getPid());
// Run once and get the results asserting that they are reasonable
JstatGcCauseResults measurement1 = jstatGcTool.measure();
measurement1.assertConsistency();
GcProvoker gcProvoker = new GcProvoker();
// Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable
gcProvoker.allocateAvailableMetaspaceAndHeap(targetMemoryUsagePercent);
// Collect garbage. Also update VM statistics
System.gc();
JstatGcCauseResults measurement2 = jstatGcTool.measure();
measurement2.assertConsistency();
// Assert that space has been utilized acordingly
JstatResults.assertSpaceUtilization(measurement2, targetMemoryUsagePercent);
new GarbageProducerTest(new JstatGcCauseTool(ProcessHandle.current().getPid())).run();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,43 +21,23 @@
* questions.
*/
import utils.*;
/*
* @test
* @summary Test checks output displayed with jstat -gc.
* Test scenario:
* tests forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show that ~70% of heap is utilized (OC/OU ~= 70%).
* test forces debuggee application eat ~70% of heap and runs jstat.
* jstat should show actual usage of old gen (OC/OU ~= old gen usage).
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @library ../share
* @run main/othervm -XX:+UsePerfData -XX:InitialHeapSize=128M -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcTest02
* @run main/othervm -XX:+UsePerfData -XX:MaxNewSize=4m -XX:MaxHeapSize=128M -XX:MaxMetaspaceSize=128M GcTest02
*/
import utils.*;
public class GcTest02 {
private final static float targetMemoryUsagePercent = 0.7f;
public static void main(String[] args) throws Exception {
// We will be running "jstat -gc" tool
JstatGcTool jstatGcTool = new JstatGcTool(ProcessHandle.current().getPid());
// Run once and get the results asserting that they are reasonable
JstatGcResults measurement1 = jstatGcTool.measure();
measurement1.assertConsistency();
GcProvoker gcProvoker = new GcProvoker();
// Eat metaspace and heap then run the tool again and get the results asserting that they are reasonable
gcProvoker.allocateAvailableMetaspaceAndHeap(targetMemoryUsagePercent);
// Collect garbage. Also updates VM statistics
System.gc();
JstatGcResults measurement2 = jstatGcTool.measure();
measurement2.assertConsistency();
// Assert that space has been utilized acordingly
JstatResults.assertSpaceUtilization(measurement2, targetMemoryUsagePercent);
new GarbageProducerTest(new JstatGcTool(ProcessHandle.current().getPid())).run();
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package utils;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;
/**
* This is an class used to allocate specified amount of metaspace and heap.
*/
public class GarbageProducer {
// Uses fixed small objects to avoid Humongous objects allocation with G1 GC.
private static final int MEMORY_CHUNK = 2048;
public static List<Object> allocatedMetaspace;
public static List<Object> allocatedMemory;
private final MemoryMXBean memoryMXBean;
private final float targetMemoryUsagePercent;
private final long targetMemoryUsage;
/**
* @param targetMemoryUsagePercent how many percent of metaspace and heap to
* allocate
*/
public GarbageProducer(float targetMemoryUsagePercent) {
memoryMXBean = ManagementFactory.getMemoryMXBean();
this.targetMemoryUsagePercent = targetMemoryUsagePercent;
targetMemoryUsage = (long) (memoryMXBean.getHeapMemoryUsage().getMax() * targetMemoryUsagePercent);
}
/**
* Allocates heap and metaspace upon exit targetMemoryUsagePercent percents
* of heap and metaspace have been consumed.
*/
public void allocateMetaspaceAndHeap() {
// Metaspace should be filled before Java Heap to prevent unexpected OOME
// in the Java Heap while filling Metaspace
allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent);
allocatedMemory = allocateGarbage(targetMemoryUsage);
}
private List<Object> eatMetaspace(float targetUsage) {
List<Object> list = new ArrayList<>();
MemoryPoolMXBean metaspacePool = getMatchedMemoryPool(".*Metaspace.*");
float currentUsage;
GeneratedClassProducer gp = new GeneratedClassProducer();
do {
try {
list.add(gp.create(0));
} catch (OutOfMemoryError oome) {
list = null;
throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace.");
}
MemoryUsage memoryUsage = metaspacePool.getUsage();
currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax());
} while (currentUsage < targetUsage);
return list;
}
private MemoryPoolMXBean getMatchedMemoryPool(String patternPoolName) {
return ManagementFactory.getMemoryPoolMXBeans().stream()
.filter(bean -> bean.getName().matches(patternPoolName))
.findFirst()
.orElseThrow(() -> new RuntimeException("Cannot find '" + patternPoolName + "' memory pool."));
}
private List<Object> allocateGarbage(long targetMemoryUsage) {
List<Object> list = new ArrayList<>();
do {
try {
list.add(new byte[MEMORY_CHUNK]);
} catch (OutOfMemoryError e) {
list = null;
throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "'");
}
} while (memoryMXBean.getHeapMemoryUsage().getUsed() < targetMemoryUsage);
return list;
}
/**
* Returns allocation rate for old gen based on appropriate MemoryPoolMXBean
* memory usage.
*
* @return allocation rate
*/
public float getOldGenAllocationRatio() {
MemoryPoolMXBean oldGenBean = getMatchedMemoryPool(".*Old.*|.*Tenured.*");
MemoryUsage usage = oldGenBean.getUsage();
System.out.format("Memory usage for %1s.\n", oldGenBean.getName());
System.out.format("Used: %1d\n", usage.getUsed());
System.out.format("Commited: %1d\n", usage.getCommitted());
System.out.format("Max: %1d\n", usage.getMax());
return ((float) usage.getUsed()) / usage.getCommitted();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,9 +22,6 @@
*/
package utils;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;
@ -36,11 +33,7 @@ import java.util.List;
public class GcProvoker{
// Uses fixed small objects to avoid Humongous objects allocation in G1
public static final int MEMORY_CHUNK = 2048;
public static final float ALLOCATION_TOLERANCE = 0.05f;
public static List<Object> allocatedMetaspace;
public static List<Object> allocatedMemory;
private static final int MEMORY_CHUNK = 2048;
private final Runtime runtime;
@ -61,21 +54,6 @@ public class GcProvoker{
return list;
}
private List<Object> allocateAvailableHeap(float targetUsage) {
// Calculates size of free memory after allocation with small tolerance.
long minFreeMemory = (long) ((1.0 - (targetUsage + ALLOCATION_TOLERANCE)) * runtime.maxMemory());
List<Object> list = new ArrayList<>();
do {
try {
list.add(new byte[MEMORY_CHUNK]);
} catch (OutOfMemoryError e) {
list = null;
throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory.");
}
} while (runtime.freeMemory() > minFreeMemory);
return list;
}
/**
* This method provokes a GC
*/
@ -93,65 +71,7 @@ public class GcProvoker{
}
}
/**
* Allocates heap and metaspace upon exit not less than targetMemoryUsagePercent percents
* of heap and metaspace have been consumed.
*
* @param targetMemoryUsagePercent how many percent of heap and metaspace to
* allocate
*/
public void allocateMetaspaceAndHeap(float targetMemoryUsagePercent) {
// Metaspace should be filled before Java Heap to prevent unexpected OOME
// in the Java Heap while filling Metaspace
allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent);
allocatedMemory = allocateHeap(targetMemoryUsagePercent);
}
/**
* Allocates heap and metaspace upon exit targetMemoryUsagePercent percents
* of heap and metaspace have been consumed.
*
* @param targetMemoryUsagePercent how many percent of heap and metaspace to
* allocate
*/
public void allocateAvailableMetaspaceAndHeap(float targetMemoryUsagePercent) {
// Metaspace should be filled before Java Heap to prevent unexpected OOME
// in the Java Heap while filling Metaspace
allocatedMetaspace = eatMetaspace(targetMemoryUsagePercent);
allocatedMemory = allocateAvailableHeap(targetMemoryUsagePercent);
}
private List<Object> eatMetaspace(float targetUsage) {
List<Object> list = new ArrayList<>();
final String metaspacePoolName = "Metaspace";
MemoryPoolMXBean metaspacePool = null;
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
if (pool.getName().contains(metaspacePoolName)) {
metaspacePool = pool;
break;
}
}
if (metaspacePool == null) {
throw new RuntimeException("MXBean for Metaspace pool wasn't found");
}
float currentUsage;
GeneratedClassProducer gp = new GeneratedClassProducer();
do {
try {
list.add(gp.create(0));
} catch (OutOfMemoryError oome) {
list = null;
throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace.");
}
MemoryUsage memoryUsage = metaspacePool.getUsage();
currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax());
} while (currentUsage < targetUsage);
return list;
}
public GcProvoker() {
runtime = Runtime.getRuntime();
}
}

View File

@ -1,113 +0,0 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package utils;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;
/**
*
* Utilities to provoke GC in various ways
*/
public class GcProvokerImpl implements GcProvoker {
private static List<Object> eatenMetaspace;
private static List<Object> eatenMemory;
static List<Object> eatHeapMemory(float targetUsage) {
long maxMemory = Runtime.getRuntime().maxMemory();
// uses fixed small objects to avoid Humongous objects allocation in G1
int memoryChunk = 2048;
List<Object> list = new ArrayList<>();
long used = 0;
long target = (long) (maxMemory * targetUsage);
while (used < target) {
try {
list.add(new byte[memoryChunk]);
used += memoryChunk;
} catch (OutOfMemoryError e) {
list = null;
throw new RuntimeException("Unexpected OOME '" + e.getMessage() + "' while eating " + targetUsage + " of heap memory.");
}
}
return list;
}
@Override
public void provokeGc() {
for (int i = 0; i < 3; i++) {
long edenSize = Pools.getEdenCommittedSize();
long heapSize = Pools.getHeapCommittedSize();
float targetPercent = ((float) edenSize) / (heapSize);
if ((targetPercent < 0) || (targetPercent > 1.0)) {
throw new RuntimeException("Error in the percent calculation" + " (eden size: " + edenSize + ", heap size: " + heapSize + ", calculated eden percent: " + targetPercent + ")");
}
eatHeapMemory(targetPercent);
eatHeapMemory(targetPercent);
System.gc();
}
}
@Override
public void eatMetaspaceAndHeap(float targetMemoryUsagePercent) {
// Metaspace should be filled before Java Heap to prevent unexpected OOME
// in the Java Heap while filling Metaspace
eatenMetaspace = eatMetaspace(targetMemoryUsagePercent);
eatenMemory = eatHeapMemory(targetMemoryUsagePercent);
}
private static List<Object> eatMetaspace(float targetUsage) {
List<Object> list = new ArrayList<>();
final String metaspacePoolName = "Metaspace";
MemoryPoolMXBean metaspacePool = null;
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
if (pool.getName().contains(metaspacePoolName)) {
metaspacePool = pool;
break;
}
}
if (metaspacePool == null) {
throw new RuntimeException("MXBean for Metaspace pool wasn't found");
}
float currentUsage;
GeneratedClassProducer gp = new GeneratedClassProducer();
do {
try {
list.add(gp.create(0));
} catch (OutOfMemoryError oome) {
list = null;
throw new RuntimeException("Unexpected OOME '" + oome.getMessage() + "' while eating " + targetUsage + " of Metaspace.");
}
MemoryUsage memoryUsage = metaspacePool.getUsage();
currentUsage = (((float) memoryUsage.getUsed()) / memoryUsage.getMax());
} while (currentUsage < targetUsage);
return list;
}
public GcProvokerImpl() {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,7 @@ public class JstatGcCapacityResults extends JstatResults {
/**
* Checks the overall consistency of the results reported by the tool
*/
@Override
public void assertConsistency() {
// Check exit code
@ -117,8 +118,6 @@ public class JstatGcCapacityResults extends JstatResults {
float MC = getFloatValue("MC");
assertThat(MC >= MCMN, "MC < MCMN (generation capacity < min generation capacity)");
assertThat(MC <= MCMX, "MGC > MCMX (generation capacity > max generation capacity)");
}
/**
@ -139,21 +138,4 @@ public class JstatGcCapacityResults extends JstatResults {
}
return false;
}
private static final float FLOAT_COMPARISON_TOLERANCE = 0.0011f;
private static boolean checkFloatIsSum(float sum, float... floats) {
for (float f : floats) {
sum -= f;
}
return Math.abs(sum) <= FLOAT_COMPARISON_TOLERANCE;
}
private void assertThat(boolean b, String message) {
if (!b) {
throw new RuntimeException(message);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -56,6 +56,7 @@ public class JstatGcCauseResults extends JstatResults {
/**
* Checks the overall consistency of the results reported by the tool
*/
@Override
public void assertConsistency() {
assertThat(getExitCode() == 0, "Unexpected exit code: " + getExitCode());
@ -83,21 +84,4 @@ public class JstatGcCauseResults extends JstatResults {
assertThat(checkFloatIsSum(GCT, YGCT, FGCT), "GCT != (YGCT + FGCT) " + "(GCT = " + GCT + ", YGCT = " + YGCT
+ ", FGCT = " + FGCT + ", (YCGT + FGCT) = " + (YGCT + FGCT) + ")");
}
private static final float FLOAT_COMPARISON_TOLERANCE = 0.0011f;
private static boolean checkFloatIsSum(float sum, float... floats) {
for (float f : floats) {
sum -= f;
}
return Math.abs(sum) <= FLOAT_COMPARISON_TOLERANCE;
}
private void assertThat(boolean b, String message) {
if (!b) {
throw new RuntimeException(message);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -54,6 +54,7 @@ public class JstatGcNewResults extends JstatResults {
/**
* Checks the overall consistency of the results reported by the tool
*/
@Override
public void assertConsistency() {
assertThat(getExitCode() == 0, "Unexpected exit code: " + getExitCode());
@ -84,10 +85,4 @@ public class JstatGcNewResults extends JstatResults {
int MTT = getIntValue("MTT");
assertThat(TT <= MTT, "TT > MTT (tenuring threshold > maximum tenuring threshold)");
}
private void assertThat(boolean b, String message) {
if (!b) {
throw new RuntimeException(message);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -61,6 +61,7 @@ public class JstatGcResults extends JstatResults {
/**
* Checks the overall consistency of the results reported by the tool
*/
@Override
public void assertConsistency() {
assertThat(getExitCode() == 0, "Unexpected exit code: " + getExitCode());
@ -112,21 +113,4 @@ public class JstatGcResults extends JstatResults {
assertThat(checkFloatIsSum(GCT, YGCT, FGCT), "GCT != (YGCT + FGCT) " + "(GCT = " + GCT + ", YGCT = " + YGCT
+ ", FGCT = " + FGCT + ", (YCGT + FGCT) = " + (YGCT + FGCT) + ")");
}
private static final float FLOAT_COMPARISON_TOLERANCE = 0.0011f;
private static boolean checkFloatIsSum(float sum, float... floats) {
for (float f : floats) {
sum -= f;
}
return Math.abs(sum) <= FLOAT_COMPARISON_TOLERANCE;
}
private void assertThat(boolean b, String message) {
if (!b) {
throw new RuntimeException(message);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,8 @@ import common.ToolResults;
*/
abstract public class JstatResults extends ToolResults {
private static final float FLOAT_COMPARISON_TOLERANCE = 0.0011f;
public JstatResults(ToolResults rawResults) {
super(rawResults);
}
@ -110,38 +112,61 @@ abstract public class JstatResults extends ToolResults {
* space has been utilized
*/
public static void assertSpaceUtilization(JstatResults measurement, float targetMemoryUsagePercent) {
assertSpaceUtilization(measurement, targetMemoryUsagePercent, targetMemoryUsagePercent);
}
/**
* Helper function to assert the utilization of the space
*
* @param measurement - measurement results to analyze
* @param targetMetaspaceUsagePercent -assert that not less than this amount
* of metaspace has been utilized
* @param targetOldSpaceUsagePercent -assert that not less than this amount
* of old space has been utilized
*/
public static void assertSpaceUtilization(JstatResults measurement, float targetMetaspaceUsagePercent,
float targetOldSpaceUsagePercent) {
if (measurement.valueExists("OU")) {
float OC = measurement.getFloatValue("OC");
float OU = measurement.getFloatValue("OU");
assertThat((OU / OC) > targetMemoryUsagePercent, "Old space utilization should be > "
+ (targetMemoryUsagePercent * 100) + "%, actually OU / OC = " + (OU / OC));
assertThat((OU / OC) > targetOldSpaceUsagePercent, "Old space utilization should be > "
+ (targetOldSpaceUsagePercent * 100) + "%, actually OU / OC = " + (OU / OC));
}
if (measurement.valueExists("MU")) {
float MC = measurement.getFloatValue("MC");
float MU = measurement.getFloatValue("MU");
assertThat((MU / MC) > targetMemoryUsagePercent, "Metaspace utilization should be > "
+ (targetMemoryUsagePercent * 100) + "%, actually MU / MC = " + (MU / MC));
assertThat((MU / MC) > targetMetaspaceUsagePercent, "Metaspace utilization should be > "
+ (targetMetaspaceUsagePercent * 100) + "%, actually MU / MC = " + (MU / MC));
}
if (measurement.valueExists("O")) {
float O = measurement.getFloatValue("O");
assertThat(O > targetMemoryUsagePercent * 100, "Old space utilization should be > "
+ (targetMemoryUsagePercent * 100) + "%, actually O = " + O);
assertThat(O > targetOldSpaceUsagePercent * 100, "Old space utilization should be > "
+ (targetOldSpaceUsagePercent * 100) + "%, actually O = " + O);
}
if (measurement.valueExists("M")) {
float M = measurement.getFloatValue("M");
assertThat(M > targetMemoryUsagePercent * 100, "Metaspace utilization should be > "
+ (targetMemoryUsagePercent * 100) + "%, actually M = " + M);
assertThat(M > targetMetaspaceUsagePercent * 100, "Metaspace utilization should be > "
+ (targetMetaspaceUsagePercent * 100) + "%, actually M = " + M);
}
}
private static void assertThat(boolean result, String message) {
public static void assertThat(boolean result, String message) {
if (!result) {
throw new RuntimeException(message);
}
}
public static boolean checkFloatIsSum(float sum, float... floats) {
for (float f : floats) {
sum -= f;
}
return Math.abs(sum) <= FLOAT_COMPARISON_TOLERANCE;
}
abstract public void assertConsistency();
}