8205725: Update the JVMTI Spec for Heap Sampling

Update the JVMTI Spec for Heap Sampling

Reviewed-by: amenkov, sspitsyn
This commit is contained in:
Jean Christophe Beyler 2018-07-17 19:59:38 -07:00 committed by Jean Christophe Beyler
parent 4e92c2dfdc
commit 3380b0d0ef
13 changed files with 103 additions and 94 deletions

@ -10369,7 +10369,7 @@ myInit() {
<description> <description>
Can generate sampled allocation events. Can generate sampled allocation events.
If this capability is enabled then the heap sampling method If this capability is enabled then the heap sampling method
<functionlink id="SetHeapSamplingRate"></functionlink> can be <functionlink id="SetHeapSamplingInterval"></functionlink> can be
called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated. called and <eventlink id="SampledObjectAlloc"></eventlink> events can be generated.
</description> </description>
</capabilityfield> </capabilityfield>
@ -11552,41 +11552,47 @@ myInit() {
</category> </category>
<category id="heap_monitoring" label="Heap Monitoring"> <category id="heap_monitoring" label="Heap Monitoring">
<function id="SetHeapSamplingRate" phase="onload" num="156" since="11"> <function id="SetHeapSamplingInterval" phase="onload" num="156" since="11">
<synopsis>Set Heap Sampling Rate</synopsis> <synopsis>Set Heap Sampling Interval</synopsis>
<description> <description>
Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated. Generate a <eventlink id="SampledObjectAlloc"/> event when objects are allocated.
Each thread keeps a counter of bytes allocated. The event will only be generated Each thread keeps a counter of bytes allocated. The event will only be generated
when that counter exceeds an average of <paramlink id="sampling_rate"></paramlink> when that counter exceeds an average of <paramlink id="sampling_interval"></paramlink>
since the last sample. since the last sample.
<p/> <p/>
Setting <paramlink id="sampling_rate"></paramlink> to 0 will cause an event to be Setting <paramlink id="sampling_interval"></paramlink> to 0 will cause an event to be
generated by each allocation supported by the system. generated by each allocation supported by the system once the new interval is taken into account.
<p/>
Note that updating the new sampling interval might take various number of allocations
to provoke internal data structure updates. Therefore it is important to
consider the sampling interval as an average. This includes the interval 0, where events
might not be generated straight away for each allocation.
</description> </description>
<origin>new</origin> <origin>new</origin>
<capabilities> <capabilities>
<required id="can_generate_sampled_object_alloc_events"></required> <required id="can_generate_sampled_object_alloc_events"></required>
</capabilities> </capabilities>
<parameters> <parameters>
<param id="sampling_rate"> <param id="sampling_interval">
<jint/> <jint/>
<description> <description>
The sampling rate in bytes. The sampler uses a statistical approach to The sampling interval in bytes. The sampler uses a statistical approach to
generate an event, on average, once for every <paramlink id="sampling_rate"/> bytes of generate an event, on average, once for every <paramlink id="sampling_interval"/> bytes of
memory allocated by a given thread. memory allocated by a given thread.
<p/> <p/>
Passing 0 as a sampling rate generates a sample for every allocation. Once the new sampling interval is taken into account, 0 as a sampling interval will generate
a sample for every allocation.
<p/> <p/>
Note: The overhead of this feature is directly correlated with the sampling rate. Note: The overhead of this feature is directly correlated with the sampling interval.
A high sampling rate, such as 1024 bytes, will incur a high overhead. A high sampling interval, such as 1024 bytes, will incur a high overhead.
A lower rate, such as 1024KB, will have a much lower overhead. Sampling should only A lower interval, such as 1024KB, will have a much lower overhead. Sampling should only
be used with an understanding that it may impact performance. be used with an understanding that it may impact performance.
</description> </description>
</param> </param>
</parameters> </parameters>
<errors> <errors>
<error id="JVMTI_ERROR_ILLEGAL_ARGUMENT"> <error id="JVMTI_ERROR_ILLEGAL_ARGUMENT">
<paramlink id="sampling_rate"></paramlink> is less than zero. <paramlink id="sampling_interval"></paramlink> is less than zero.
</error> </error>
</errors> </errors>
</function> </function>
@ -13586,20 +13592,23 @@ myInit() {
id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11"> id="SampledObjectAlloc" const="JVMTI_EVENT_SAMPLED_OBJECT_ALLOC" num="86" since="11">
<description> <description>
Sent when an allocated object is sampled. Sent when an allocated object is sampled.
By default, the sampling rate is a geometric variable with a 512KB mean. By default, the sampling interval is set to 512KB. The sampling is semi-random to avoid
pattern-based bias and provides an approximate overall average interval over long periods of
sampling.
<p/>
Each thread tracks how many bytes it has allocated since it sent the last event. Each thread tracks how many bytes it has allocated since it sent the last event.
When the number of bytes exceeds the sampling rate, it will send another event. When the number of bytes exceeds the sampling interval, it will send another event.
This implies that, on average, one object will be sampled every time a thread has This implies that, on average, one object will be sampled every time a thread has
allocated 512KB bytes since the last sample. allocated 512KB bytes since the last sample.
<p/> <p/>
Note that this is a geometric variable: it will not sample every 512KB precisely. Note that the sampler is pseudo-random: it will not sample every 512KB precisely.
The goal of this is to ensure high quality sampling even if allocation is The goal of this is to ensure high quality sampling even if allocation is
happening in a fixed pattern (i.e., the same set of objects are being allocated happening in a fixed pattern (i.e., the same set of objects are being allocated
every 512KB). every 512KB).
<p/> <p/>
If another sampling rate is required, the user can call If another sampling interval is required, the user can call
<functionlink id="SetHeapSamplingRate"></functionlink> with a strictly positive integer value, representing <functionlink id="SetHeapSamplingInterval"></functionlink> with a strictly positive integer value,
the new sampling rate. representing the new sampling interval.
<p/> <p/>
This event is sent once the sampled allocation has been performed. It provides the object, stack trace This event is sent once the sampled allocation has been performed. It provides the object, stack trace
of the allocation, the thread allocating, the size of allocation, and the object's class. of the allocation, the thread allocating, the size of allocation, and the object's class.

@ -3644,13 +3644,13 @@ JvmtiEnv::GetAvailableProcessors(jint* processor_count_ptr) {
} /* end GetAvailableProcessors */ } /* end GetAvailableProcessors */
jvmtiError jvmtiError
JvmtiEnv::SetHeapSamplingRate(jint sampling_rate) { JvmtiEnv::SetHeapSamplingInterval(jint sampling_interval) {
if (sampling_rate < 0) { if (sampling_interval < 0) {
return JVMTI_ERROR_ILLEGAL_ARGUMENT; return JVMTI_ERROR_ILLEGAL_ARGUMENT;
} }
ThreadHeapSampler::set_sampling_rate(sampling_rate); ThreadHeapSampler::set_sampling_interval(sampling_interval);
return JVMTI_ERROR_NONE; return JVMTI_ERROR_NONE;
} /* end SetHeapSamplingRate */ } /* end SetHeapSamplingInterval */
// //
// System Properties functions // System Properties functions

@ -31,7 +31,7 @@
// Cheap random number generator // Cheap random number generator
uint64_t ThreadHeapSampler::_rnd; uint64_t ThreadHeapSampler::_rnd;
// Default is 512kb. // Default is 512kb.
int ThreadHeapSampler::_sampling_rate = 512 * 1024; int ThreadHeapSampler::_sampling_interval = 512 * 1024;
int ThreadHeapSampler::_enabled; int ThreadHeapSampler::_enabled;
// Statics for the fast log // Statics for the fast log
@ -69,7 +69,7 @@ static double fast_log2(const double & d) {
// Generates a geometric variable with the specified mean (512K by default). // Generates a geometric variable with the specified mean (512K by default).
// This is done by generating a random number between 0 and 1 and applying // This is done by generating a random number between 0 and 1 and applying
// the inverse cumulative distribution function for an exponential. // the inverse cumulative distribution function for an exponential.
// Specifically: Let m be the inverse of the sample rate, then // Specifically: Let m be the inverse of the sample interval, then
// the probability distribution function is m*exp(-mx) so the CDF is // the probability distribution function is m*exp(-mx) so the CDF is
// p = 1 - exp(-mx), so // p = 1 - exp(-mx), so
// q = 1 - p = exp(-mx) // q = 1 - p = exp(-mx)
@ -96,14 +96,14 @@ void ThreadHeapSampler::pick_next_geometric_sample() {
// negative answer. // negative answer.
double log_val = (fast_log2(q) - 26); double log_val = (fast_log2(q) - 26);
double result = double result =
(0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_rate())) + 1; (0.0 < log_val ? 0.0 : log_val) * (-log(2.0) * (get_sampling_interval())) + 1;
assert(result > 0 && result < SIZE_MAX, "Result is not in an acceptable range."); assert(result > 0 && result < SIZE_MAX, "Result is not in an acceptable range.");
size_t rate = static_cast<size_t>(result); size_t interval = static_cast<size_t>(result);
_bytes_until_sample = rate; _bytes_until_sample = interval;
} }
void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) { void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) {
if (get_sampling_rate() == 1) { if (get_sampling_interval() == 1) {
_bytes_until_sample = 1; _bytes_until_sample = 1;
return; return;
} }
@ -161,12 +161,12 @@ void ThreadHeapSampler::disable() {
OrderAccess::release_store(&_enabled, 0); OrderAccess::release_store(&_enabled, 0);
} }
int ThreadHeapSampler::get_sampling_rate() { int ThreadHeapSampler::get_sampling_interval() {
return OrderAccess::load_acquire(&_sampling_rate); return OrderAccess::load_acquire(&_sampling_interval);
} }
void ThreadHeapSampler::set_sampling_rate(int sampling_rate) { void ThreadHeapSampler::set_sampling_interval(int sampling_interval) {
OrderAccess::release_store(&_sampling_rate, sampling_rate); OrderAccess::release_store(&_sampling_interval, sampling_interval);
} }
// Methods used in assertion mode to check if a collector is present or not at // Methods used in assertion mode to check if a collector is present or not at

@ -36,7 +36,7 @@ class ThreadHeapSampler {
void pick_next_geometric_sample(); void pick_next_geometric_sample();
void pick_next_sample(size_t overflowed_bytes = 0); void pick_next_sample(size_t overflowed_bytes = 0);
static int _enabled; static int _enabled;
static int _sampling_rate; static int _sampling_interval;
// Used for assertion mode to determine if there is a path to a TLAB slow path // Used for assertion mode to determine if there is a path to a TLAB slow path
// without a collector present. // without a collector present.
@ -63,8 +63,8 @@ class ThreadHeapSampler {
static void enable(); static void enable();
static void disable(); static void disable();
static void set_sampling_rate(int sampling_rate); static void set_sampling_interval(int sampling_interval);
static int get_sampling_rate(); static int get_sampling_interval();
bool sampling_collector_present() const; bool sampling_collector_present() const;
bool remove_sampling_collector(); bool remove_sampling_collector();

@ -45,8 +45,8 @@ public class HeapMonitor {
} }
} }
/** Set a specific sampling rate, 0 samples every allocation. */ /** Set a specific sampling interval, 0 samples every allocation. */
public native static void setSamplingRate(int rate); public native static void setSamplingInterval(int interval);
public native static void enableSamplingEvents(); public native static void enableSamplingEvents();
public native static boolean enableSamplingEventsForTwoThreads(Thread firstThread, Thread secondThread); public native static boolean enableSamplingEventsForTwoThreads(Thread firstThread, Thread secondThread);
public native static void disableSamplingEvents(); public native static void disableSamplingEvents();
@ -131,7 +131,7 @@ public class HeapMonitor {
public static int[][][] sampleEverything() { public static int[][][] sampleEverything() {
enableSamplingEvents(); enableSamplingEvents();
setSamplingRate(0); setSamplingInterval(0);
// Loop around an allocation loop and wait until the tlabs have settled. // Loop around an allocation loop and wait until the tlabs have settled.
final int maxTries = 10; final int maxTries = 10;

@ -26,7 +26,7 @@ package MyPackage;
/** /**
* @test * @test
* @build Frame HeapMonitor * @build Frame HeapMonitor
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays. * @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
* @compile HeapMonitorArrayAllSampledTest.java * @compile HeapMonitorArrayAllSampledTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorArrayAllSampledTest * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorArrayAllSampledTest
*/ */
@ -46,7 +46,7 @@ public class HeapMonitorArrayAllSampledTest {
public static void main(String[] args) { public static void main(String[] args) {
int sizes[] = {1000, 10000, 100000, 1000000}; int sizes[] = {1000, 10000, 100000, 1000000};
HeapMonitor.setSamplingRate(0); HeapMonitor.setSamplingInterval(0);
HeapMonitor.enableSamplingEvents(); HeapMonitor.enableSamplingEvents();
for (int currentSize : sizes) { for (int currentSize : sizes) {
@ -56,8 +56,8 @@ public class HeapMonitorArrayAllSampledTest {
allocate(currentSize); allocate(currentSize);
// 10% error ensures a sanity test without becoming flaky. // 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling rate. This means that the test could be // statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case. // unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples(maxIteration, 10)) { if (!HeapMonitor.statsHaveExpectedNumberSamples(maxIteration, 10)) {
throw new RuntimeException("Statistics should show about " + maxIteration + " samples."); throw new RuntimeException("Statistics should show about " + maxIteration + " samples.");

@ -25,7 +25,7 @@ package MyPackage;
/** /**
* @test * @test
* @summary Verifies the JVMTI SetHeapSamplingRate returns an illegal argument for negative ints. * @summary Verifies the JVMTI SetHeapSamplingInterval returns an illegal argument for negative ints.
* @build Frame HeapMonitor * @build Frame HeapMonitor
* @compile HeapMonitorIllegalArgumentTest.java * @compile HeapMonitorIllegalArgumentTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorIllegalArgumentTest

@ -26,7 +26,7 @@ package MyPackage;
/** /**
* @test * @test
* @build Frame HeapMonitor * @build Frame HeapMonitor
* @summary Verifies the JVMTI Heap Monitor rate when allocating arrays. * @summary Verifies the JVMTI Heap Monitor interval when allocating arrays.
* @compile HeapMonitorStatArrayCorrectnessTest.java * @compile HeapMonitorStatArrayCorrectnessTest.java
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatArrayCorrectnessTest * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatArrayCorrectnessTest
*/ */
@ -58,7 +58,7 @@ public class HeapMonitorStatArrayCorrectnessTest {
// 111 is as good a number as any. // 111 is as good a number as any.
final int samplingMultiplier = 111; final int samplingMultiplier = 111;
HeapMonitor.setSamplingRate(samplingMultiplier * currentSize); HeapMonitor.setSamplingInterval(samplingMultiplier * currentSize);
allocate(currentSize); allocate(currentSize);
@ -79,8 +79,8 @@ public class HeapMonitorStatArrayCorrectnessTest {
expected /= samplingMultiplier; expected /= samplingMultiplier;
// 10% error ensures a sanity test without becoming flaky. // 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling rate. This means that the test could be // statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case. // unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) { if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples."); throw new RuntimeException("Statistics should show about " + expected + " samples.");

@ -50,12 +50,12 @@ public class HeapMonitorStatObjectCorrectnessTest {
HeapMonitor.disableSamplingEvents(); HeapMonitor.disableSamplingEvents();
} }
private static void testBigAllocationRate() { private static void testBigAllocationInterval() {
final int sizeObject = 1400; final int sizeObject = 1400;
// 111 is as good a number as any. // 111 is as good a number as any.
final int samplingMultiplier = 111; final int samplingMultiplier = 111;
HeapMonitor.setSamplingRate(samplingMultiplier * sizeObject); HeapMonitor.setSamplingInterval(samplingMultiplier * sizeObject);
allocate(); allocate();
@ -79,8 +79,8 @@ public class HeapMonitorStatObjectCorrectnessTest {
expected /= samplingMultiplier; expected /= samplingMultiplier;
// 10% error ensures a sanity test without becoming flaky. // 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling rate. This means that the test could be // statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case. // unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) { if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples."); throw new RuntimeException("Statistics should show about " + expected + " samples.");
@ -97,15 +97,15 @@ public class HeapMonitorStatObjectCorrectnessTest {
private static void testEveryAllocationSampled() { private static void testEveryAllocationSampled() {
// 0 means sample every allocation. // 0 means sample every allocation.
HeapMonitor.setSamplingRate(0); HeapMonitor.setSamplingInterval(0);
allocate(); allocate();
double expected = maxIteration; double expected = maxIteration;
// 10% error ensures a sanity test without becoming flaky. // 10% error ensures a sanity test without becoming flaky.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling rate. This means that the test could be // statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case. // unlucky and not achieve the mean average fast enough for the test case.
if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) { if (!HeapMonitor.statsHaveExpectedNumberSamples((int) expected, 10)) {
throw new RuntimeException("Statistics should show about " + expected + " samples."); throw new RuntimeException("Statistics should show about " + expected + " samples.");
@ -113,7 +113,7 @@ public class HeapMonitorStatObjectCorrectnessTest {
} }
public static void main(String[] args) { public static void main(String[] args) {
testBigAllocationRate(); testBigAllocationInterval();
testEveryAllocationSampled(); testEveryAllocationSampled();
} }

@ -25,20 +25,20 @@ package MyPackage;
/** /**
* @test * @test
* @summary Verifies the JVMTI Heap Monitor sampling rate average. * @summary Verifies the JVMTI Heap Monitor sampling interval average.
* @build Frame HeapMonitor * @build Frame HeapMonitor
* @compile HeapMonitorStatRateTest.java * @compile HeapMonitorStatIntervalTest.java
* @requires vm.compMode != "Xcomp" * @requires vm.compMode != "Xcomp"
* @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatRateTest * @run main/othervm/native -agentlib:HeapMonitorTest MyPackage.HeapMonitorStatIntervalTest
*/ */
public class HeapMonitorStatRateTest { public class HeapMonitorStatIntervalTest {
private native static double getAverageRate(); private native static double getAverageInterval();
private static boolean testRateOnce(int rate, boolean throwIfFailure) { private static boolean testIntervalOnce(int interval, boolean throwIfFailure) {
HeapMonitor.resetEventStorage(); HeapMonitor.resetEventStorage();
HeapMonitor.setSamplingRate(rate); HeapMonitor.setSamplingInterval(interval);
HeapMonitor.enableSamplingEvents(); HeapMonitor.enableSamplingEvents();
@ -54,7 +54,7 @@ public class HeapMonitorStatRateTest {
HeapMonitor.disableSamplingEvents(); HeapMonitor.disableSamplingEvents();
double expectedCount = allocationTotal * allocationIterations / rate; double expectedCount = allocationTotal * allocationIterations / interval;
double error = Math.abs(actualCount - expectedCount); double error = Math.abs(actualCount - expectedCount);
double errorPercentage = error / expectedCount * 100; double errorPercentage = error / expectedCount * 100;
@ -62,30 +62,30 @@ public class HeapMonitorStatRateTest {
boolean success = (errorPercentage < 10.0); boolean success = (errorPercentage < 10.0);
if (!success && throwIfFailure) { if (!success && throwIfFailure) {
throw new RuntimeException("Rate average over 10% for rate " + rate + " -> " + actualCount throw new RuntimeException("Interval average over 10% for interval " + interval + " -> "
+ ", " + expectedCount); + actualCount + ", " + expectedCount);
} }
return success; return success;
} }
private static void testRate(int rate) { private static void testInterval(int interval) {
// Test the rate twice, it can happen that the test is "unlucky" and the rate just goes above // Test the interval twice, it can happen that the test is "unlucky" and the interval just goes above
// the 10% mark. So try again to squash flakiness. // the 10% mark. So try again to squash flakiness.
// Flakiness is due to the fact that this test is dependent on the sampling rate, which is a // Flakiness is due to the fact that this test is dependent on the sampling interval, which is a
// statistical geometric variable around the sampling rate. This means that the test could be // statistical geometric variable around the sampling interval. This means that the test could be
// unlucky and not achieve the mean average fast enough for the test case. // unlucky and not achieve the mean average fast enough for the test case.
if (!testRateOnce(rate, false)) { if (!testIntervalOnce(interval, false)) {
testRateOnce(rate, true); testIntervalOnce(interval, true);
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
int[] tab = {1024, 8192}; int[] tab = {1024, 8192};
for (int rateIdx = 0; rateIdx < tab.length; rateIdx++) { for (int intervalIdx = 0; intervalIdx < tab.length; intervalIdx++) {
testRate(tab[rateIdx]); testInterval(tab[intervalIdx]);
} }
} }
} }

@ -41,8 +41,8 @@ public class HeapMonitorThreadTest {
final int numThreads = 5; final int numThreads = 5;
List<ThreadInformation> threadList = ThreadInformation.createThreadList(numThreads); List<ThreadInformation> threadList = ThreadInformation.createThreadList(numThreads);
// Sample at a rate of 8k. // Sample at a interval of 8k.
HeapMonitor.setSamplingRate(1 << 13); HeapMonitor.setSamplingInterval(1 << 13);
HeapMonitor.enableSamplingEvents(); HeapMonitor.enableSamplingEvents();
System.err.println("Starting threads"); System.err.println("Starting threads");

@ -62,10 +62,10 @@ public class HeapMonitorVMEventsTest implements Cloneable {
double diff = Math.abs(first - second) * 100; double diff = Math.abs(first - second) * 100;
diff /= first; diff /= first;
// Accept a 10% error rate: with objects being allocated: this allows a bit of room in // Accept a 10% error interval: with objects being allocated: this allows a bit of room in
// case other items are getting allocated during the test. // case other items are getting allocated during the test.
if (diff > 10) { if (diff > 10) {
throw new RuntimeException("Error rate is over the accepted rate: " + diff throw new RuntimeException("Error interval is over the accepted interval: " + diff
+ ": " + first + " , " + second); + ": " + first + " , " + second);
} }
} }

@ -369,7 +369,7 @@ static int event_storage_get_count(EventStorage* storage) {
return result; return result;
} }
static double event_storage_get_average_rate(EventStorage* storage) { static double event_storage_get_average_interval(EventStorage* storage) {
double accumulation = 0; double accumulation = 0;
int max_size; int max_size;
int i; int i;
@ -839,8 +839,8 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_MyPackage_HeapMonitor_setSamplingRate(JNIEnv* env, jclass cls, jint value) { Java_MyPackage_HeapMonitor_setSamplingInterval(JNIEnv* env, jclass cls, jint value) {
(*jvmti)->SetHeapSamplingRate(jvmti, value); (*jvmti)->SetHeapSamplingInterval(jvmti, value);
} }
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
@ -940,8 +940,8 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
return FALSE; return FALSE;
} }
if (check_capability_error((*jvmti)->SetHeapSamplingRate(jvmti, 1<<19), if (check_capability_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1<<19),
"Set Heap Sampling Rate")) { "Set Heap Sampling Interval")) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@ -950,23 +950,23 @@ Java_MyPackage_HeapMonitorNoCapabilityTest_allSamplingMethodsFail(JNIEnv *env,
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env, Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
jclass cls) { jclass cls) {
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 0), if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 0),
"Sampling rate 0 failed\n")){ "Sampling interval 0 failed\n")){
return FALSE; return FALSE;
} }
if (check_error((*jvmti)->SetHeapSamplingRate(jvmti, 1024), if (check_error((*jvmti)->SetHeapSamplingInterval(jvmti, 1024),
"Sampling rate 1024 failed\n")){ "Sampling interval 1024 failed\n")){
return FALSE; return FALSE;
} }
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1), if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1),
"Sampling rate -1 passed\n")){ "Sampling interval -1 passed\n")){
return FALSE; return FALSE;
} }
if (!check_error((*jvmti)->SetHeapSamplingRate(jvmti, -1024), if (!check_error((*jvmti)->SetHeapSamplingInterval(jvmti, -1024),
"Sampling rate -1024 passed\n")){ "Sampling interval -1024 passed\n")){
return FALSE; return FALSE;
} }
@ -974,8 +974,8 @@ Java_MyPackage_HeapMonitorIllegalArgumentTest_testIllegalArgument(JNIEnv *env,
} }
JNIEXPORT jdouble JNICALL JNIEXPORT jdouble JNICALL
Java_MyPackage_HeapMonitorStatRateTest_getAverageRate(JNIEnv *env, jclass cls) { Java_MyPackage_HeapMonitorStatIntervalTest_getAverageInterval(JNIEnv *env, jclass cls) {
return event_storage_get_average_rate(&global_event_storage); return event_storage_get_average_interval(&global_event_storage);
} }
typedef struct sThreadsFound { typedef struct sThreadsFound {