8212931: HeapMonitorStatIntervalTest.java fails due average calculation

Added a method to get the actual size

Reviewed-by: amenkov, sspitsyn
This commit is contained in:
Jean Christophe Beyler 2018-11-16 19:27:21 -08:00
parent 8761824649
commit 3e936d3cd9
3 changed files with 84 additions and 52 deletions

View File

@ -103,43 +103,41 @@ public class HeapMonitor {
return sum;
}
private static double averageOneElementSize;
private static native double getAverageSize();
private static long oneElementSize;
private static native long getSize(Frame[] frames, boolean checkLines);
private static long getSize(Frame[] frames) {
return getSize(frames, getCheckLines());
}
// Calculate the size of a 1-element array in order to assess average sampling interval
// via the HeapMonitorStatIntervalTest. This is needed because various GCs could add
// extra memory to arrays.
// Calculate the size of a 1-element array in order to assess sampling interval
// via the HeapMonitorStatIntervalTest.
// This is done by allocating a 1-element array and then looking in the heap monitoring
// samples for the average size of objects collected.
public static void calculateAverageOneElementSize() {
// samples for the size of an object collected.
public static void calculateOneElementSize() {
enableSamplingEvents();
// Assume a size of 24 for the average size.
averageOneElementSize = 24;
// Call allocateSize once, this allocates the internal array for the iterations.
int totalSize = 10 * 1024 * 1024;
allocateSize(totalSize);
// Reset the storage and now really track the size of the elements.
resetEventStorage();
allocateSize(totalSize);
List<Frame> frameList = allocate();
disableSamplingEvents();
// Get the actual average size.
averageOneElementSize = getAverageSize();
if (averageOneElementSize == 0) {
throw new RuntimeException("Could not calculate the average size of a 1-element array.");
frameList.add(new Frame("calculateOneElementSize", "()V", "HeapMonitor.java", 119));
Frame[] frames = frameList.toArray(new Frame[0]);
// Get the actual size.
oneElementSize = getSize(frames);
System.out.println("Element size is: " + oneElementSize);
if (oneElementSize == 0) {
throw new RuntimeException("Could get the size of a 1-element array.");
}
}
public static int allocateSize(int totalSize) {
if (averageOneElementSize == 0) {
throw new RuntimeException("Average size of a 1-element array was not calculated.");
if (oneElementSize == 0) {
throw new RuntimeException("Size of a 1-element array was not calculated.");
}
int sum = 0;
int iterations = (int) (totalSize / averageOneElementSize);
int iterations = (int) (totalSize / oneElementSize);
if (arrays == null || arrays.length < iterations) {
arrays = new int[iterations][];
@ -200,7 +198,7 @@ public class HeapMonitor {
List<Frame> frameList = allocate();
frameList.add(new Frame("allocateAndCheckFrames", "()[LMyPackage/Frame;", "HeapMonitor.java",
201));
199));
Frame[] frames = frameList.toArray(new Frame[0]);
if (!obtainedEvents(frames) && !garbageContains(frames)) {

View File

@ -58,6 +58,9 @@ public class HeapMonitorStatIntervalTest {
double errorPercentage = error / expectedCount * 100;
boolean success = (errorPercentage < 10.0);
System.out.println("Interval: " + interval + ", throw if failure: " + throwIfFailure
+ " - Expected count: " + expectedCount + ", allocationIterations: " + allocationIterations
+ ", actualCount: " + actualCount + " -> " + success);
if (!success && throwIfFailure) {
throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
@ -82,7 +85,7 @@ public class HeapMonitorStatIntervalTest {
public static void main(String[] args) {
int[] tab = {1024, 8192};
HeapMonitor.calculateAverageOneElementSize();
HeapMonitor.calculateOneElementSize();
for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
testInterval(tab[intervalIdx]);

View File

@ -502,6 +502,27 @@ static jboolean event_storage_contains(JNIEnv* env,
return FALSE;
}
static jlong event_storage_get_size(JNIEnv* env,
EventStorage* storage,
ExpectedContentFrame* frames,
size_t size,
jboolean check_lines) {
int i;
event_storage_lock(storage);
fprintf(stderr, "Getting element from storage count, size %d\n", storage->live_object_count);
for (i = 0; i < storage->live_object_count; i++) {
ObjectTrace* trace = storage->live_objects[i];
if (check_sample_content(env, trace, frames, size, check_lines, PRINT_OUT)) {
jlong result = trace->size;
event_storage_unlock(storage);
return result;
}
}
event_storage_unlock(storage);
return 0;
}
static jboolean event_storage_garbage_contains(JNIEnv* env,
EventStorage* storage,
ExpectedContentFrame* frames,
@ -968,30 +989,41 @@ Java_MyPackage_HeapMonitor_disableSamplingEvents(JNIEnv* env, jclass cls) {
"Garbage Collection Finish");
}
JNIEXPORT jboolean JNICALL
Java_MyPackage_HeapMonitor_obtainedEvents(JNIEnv* env, jclass cls,
jobjectArray frames,
jboolean check_lines) {
jboolean result;
jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
static ExpectedContentFrame *get_native_frames(JNIEnv* env, jclass cls,
jobjectArray frames) {
ExpectedContentFrame *native_frames;
jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
if (JNI_ENV_PTR(env)->ExceptionOccurred(JNI_ENV_ARG(env))) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "obtainedEvents failed with the GetArrayLength call"));
JNI_ENV_ARG2(env, "get_native_frames failed with the GetArrayLength call"));
}
native_frames = malloc(size * sizeof(*native_frames));
if (native_frames == NULL) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "Error in obtainedEvents: malloc returned NULL for native_frames allocation\n"));
JNI_ENV_ARG2(env,
"Error in get_native_frames: malloc returned NULL\n"));
}
if (fill_native_frames(env, frames, native_frames, size) != 0) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "Error in obtainedEvents: fill_native_frames returned failed status\n"));
JNI_ENV_ARG2(env,
"Error in get_native_frames: fill_native_frames returned failed status\n"));
}
return native_frames;
}
JNIEXPORT jboolean JNICALL
Java_MyPackage_HeapMonitor_obtainedEvents(JNIEnv* env, jclass cls,
jobjectArray frames,
jboolean check_lines) {
jboolean result;
jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
result = event_storage_contains(env, &global_event_storage, native_frames,
size, check_lines);
@ -1005,24 +1037,8 @@ Java_MyPackage_HeapMonitor_garbageContains(JNIEnv* env, jclass cls,
jboolean check_lines) {
jboolean result;
jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
ExpectedContentFrame *native_frames;
ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
if (JNI_ENV_PTR(env)->ExceptionOccurred(JNI_ENV_ARG(env))) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "garbageContains failed with the GetArrayLength call"));
}
native_frames = malloc(size * sizeof(*native_frames));
if (native_frames == NULL) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "Error in garbageContains: malloc returned NULL for native_frames allocation\n"));
}
if (fill_native_frames(env, frames, native_frames, size) != 0) {
JNI_ENV_PTR(env)->FatalError(
JNI_ENV_ARG2(env, "Error in garbageContains: fill_native_frames returned failed status\n"));
}
result = event_storage_garbage_contains(env, &global_event_storage,
native_frames, size, check_lines);
@ -1030,6 +1046,21 @@ Java_MyPackage_HeapMonitor_garbageContains(JNIEnv* env, jclass cls,
return result;
}
JNIEXPORT jlong JNICALL
Java_MyPackage_HeapMonitor_getSize(JNIEnv* env, jclass cls,
jobjectArray frames,
jboolean check_lines) {
jlong result = 0;
jsize size = JNI_ENV_PTR(env)->GetArrayLength(JNI_ENV_ARG2(env, frames));
ExpectedContentFrame *native_frames = get_native_frames(env, cls, frames);
result = event_storage_get_size(env, &global_event_storage,
native_frames, size, check_lines);
free(native_frames), native_frames = NULL;
return result;
}
JNIEXPORT void JNICALL
Java_MyPackage_HeapMonitor_forceGarbageCollection(JNIEnv* env, jclass cls) {
check_error((*jvmti)->ForceGarbageCollection(jvmti),