-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StatisticsHelper: Fix lack of "garbage generated" data (zeros) #25
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/** Poached from cometd 2.1.0, Apache 2 license */ | ||
/* Poached from cometd 2.1.0, Apache 2 license */ | ||
|
||
package perf; | ||
|
||
|
@@ -18,7 +18,8 @@ | |
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* @version $Revision$ $Date$ | ||
* See <a href="https://github.com/cometd/cometd/blob/2.4.x/cometd-java/cometd-java-examples/src/main/java/org/cometd/benchmark/BenchmarkHelper.java" | ||
* >BenchmarkHelper in CometD</a>. | ||
*/ | ||
public class StatisticsHelper implements Runnable { | ||
|
||
|
@@ -30,6 +31,8 @@ public class StatisticsHelper implements Runnable { | |
|
||
private final AtomicInteger starts = new AtomicInteger(); | ||
|
||
// TODO reconsider "volatile" everywhere here; we don't need synchronization based on how we use this | ||
|
||
private volatile MemoryPoolMXBean youngMemoryPool; | ||
|
||
private volatile MemoryPoolMXBean survivorMemoryPool; | ||
|
@@ -81,16 +84,15 @@ public StatisticsHelper() { | |
this.jitCompiler = ManagementFactory.getCompilationMXBean(); | ||
this.heapMemory = ManagementFactory.getMemoryMXBean(); | ||
|
||
// See this (dated) reference: | ||
// https://gist.github.com/szegedi/1474365/ebee66b04aa3468b5e3864945dc48fa3e204548a | ||
List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans(); | ||
for (MemoryPoolMXBean memoryPool : memoryPools) { | ||
if ("PS Eden Space".equals(memoryPool.getName()) || "Par Eden Space".equals(memoryPool.getName()) | ||
|| "G1 Eden".equals(memoryPool.getName())) { | ||
if (memoryPool.getName().contains("Eden")) { | ||
youngMemoryPool = memoryPool; | ||
} else if ("PS Survivor Space".equals(memoryPool.getName()) || "Par Survivor Space".equals(memoryPool.getName()) | ||
|| "G1 Survivor".equals(memoryPool.getName())) { | ||
} else if (memoryPool.getName().contains("Survivor")) { | ||
survivorMemoryPool = memoryPool; | ||
} else if ("PS Old Gen".equals(memoryPool.getName()) || "CMS Old Gen".equals(memoryPool.getName()) | ||
|| "G1 Old Gen".equals(memoryPool.getName())) { | ||
} else if (memoryPool.getName().contains("Old Gen")) { | ||
oldMemoryPool = memoryPool; | ||
} | ||
} | ||
|
@@ -112,23 +114,11 @@ public StatisticsHelper() { | |
|
||
@Override | ||
public void run() { | ||
|
||
// So we don't prevent process exit if this | ||
// is the only thread left: | ||
Thread.currentThread().setDaemon(true); | ||
|
||
if (!hasMemoryPools) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should simply throw an exception on construction if there are no memory pools? Don't all modern JVMs support this API? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The real concern is the naming assumptions of the pools that can lead to hasMemoryPools becoming false even though the API is present. See my latest commit which fixes it for JDK 11 by being more loose in the detecting the pool name (exact string vs simple contains). Still, the essence of your point stands -- what to do? I think it's a bit much to throw an exception; I'd prefer perhaps a louder warning plus an assert statement even though we don't have tests. |
||
return; | ||
|
||
// So we don't prevent process exit if this | ||
// is the only thread left: | ||
Thread.currentThread().setDaemon(true); | ||
|
||
long young = youngMemoryPool.getUsage().getUsed(); | ||
long survivor = survivorMemoryPool.getUsage().getUsed(); | ||
long old = oldMemoryPool.getUsage().getUsed(); | ||
|
||
if (!polling) { | ||
if (!polling) { // in initial state; don't save deltas | ||
polling = true; | ||
} else { | ||
if (lastYoungUsed <= young) { | ||
|
@@ -190,9 +180,11 @@ public boolean startStatistics() { | |
} | ||
System.err.println("- - - - - - - - - - - - - - - - - - - - "); | ||
|
||
scheduler = Executors.newSingleThreadScheduledExecutor(); | ||
polling = false; | ||
memoryPoller = scheduler.scheduleWithFixedDelay(this, 0, 250, TimeUnit.MILLISECONDS); | ||
if (hasMemoryPools) { | ||
scheduler = Executors.newSingleThreadScheduledExecutor(); | ||
polling = false; | ||
memoryPoller = scheduler.scheduleWithFixedDelay(this, 0, 250, TimeUnit.MILLISECONDS); | ||
} | ||
|
||
lastYoungUsed = 0; | ||
if (hasCollectors) { | ||
|
@@ -225,8 +217,13 @@ public boolean stopStatistics() { | |
if (starts.decrementAndGet() > 0) | ||
return false; | ||
|
||
memoryPoller.cancel(false); | ||
scheduler.shutdown(); | ||
if (scheduler != null) { | ||
memoryPoller.cancel(false); | ||
scheduler.shutdown(); | ||
} | ||
if (hasMemoryPools) { | ||
run();// update latest stats | ||
} | ||
|
||
System.err.println("- - - - - - - - - - - - - - - - - - - - "); | ||
System.err.println("Statistics Ended at " + new Date()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we could also make these
final
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple booleans but not the pools because they are set in the loop.