我遇到一个问题,其中ScheduledThreadPoolExecutor最终会有300万个未来任务。我试图看看什么类型的任务,所以我可以去任务的安排,但我不知道如何从这个屏幕获取任何信息(我已经尝试右键单击这些未来的任务,并在菜单中选择各种选项) 。似乎gui中缺少某些东西,比如指向实际的runnables或其他东西......
关于如何深入研究的任何想法?
答案 0 :(得分:2)
你需要知道,如果你有一个可移植的堆转储(phd,see types here),那么它不包含实际的数据(基元),那么你只能根据参考图制作你的发现(哪些类型包含对其他类型的引用。)
您可以尝试OQL。这是一种类似SQL的语言,您可以使用它来查询对象。
一个例子:
select * from java.lang.String s where s.@retainedHeapSize>10000
这会返回所有字符串,大于~10k。 你也可以制作一些函数(比如这里aggregating)。
你可以尝试一下。
如果你检查FutureTask源代码(这里是JDK6):
public class FutureTask<V> implements RunnableFuture<V> {
/** Synchronization control for FutureTask */
private final Sync sync;
...
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
...
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
实际的Runnable由Sync对象引用:
private final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -7828117401763700385L;
/** State value representing that task is running */
private static final int RUNNING = 1;
/** State value representing that task ran */
private static final int RAN = 2;
/** State value representing that task was cancelled */
private static final int CANCELLED = 4;
/** The underlying callable */
private final Callable<V> callable;
/** The result to return from get() */
private V result;
/** The exception to throw from get() */
private Throwable exception;
/**
* The thread running task. When nulled after set/cancel, this
* indicates that the results are accessible. Must be
* volatile, to ensure visibility upon completion.
*/
private volatile Thread runner;
Sync(Callable<V> callable) {
this.callable = callable;
}
因此在GUI中打开Sync对象(未在图片中打开),然后您可以检查Runnables。
我不知道你是否可以更改代码,但通常最好总是限制执行程序使用的队列大小,因为这样可以避免泄漏。或者您可以使用一些持久队列。如果您应用限制,则可以定义拒绝策略,例如拒绝,在调用者中运行等。有关详细信息,请参阅http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html。