1

我有一个问题,ScheduledThreadPoolExecutor 最终会处理 300 万个未来任务。我正在尝试查看什么类型的任务,以便我可以前往安排该任务的位置,但我不确定如何从该屏幕获取任何信息(我尝试右键单击这些未来的任务并在菜单中选择各种选项) . gui中似乎缺少一些东西,比如指向实际可运行文件的链接或其他东西......

关于如何进一步深入研究的任何想法?

在此处输入图像描述

4

1 回答 1

2

一些一般的东西

您需要知道,如果您有一个可移植堆转储(phd,请参阅此处的类型),那么它不包含实际数据(原语),因此您可以仅根据参考映射(哪些类型持有参考其他类型)。

您可以尝试OQL。这是一种类似 SQL 的语言,您可以使用它来查询您的对象。

一个例子:

select * from java.lang.String s where s.@retainedHeapSize>10000

这会返回所有大于 ~10k 的字符串。您还可以制作一些功能(例如这里的聚合)。

你可以试一试。

至于现在的问题

如果您检查 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

于 2012-11-18T19:42:49.400 回答