1

我正在编写的一些 Java 代码有一个非常奇怪的错误。如果我运行一些我编写的并行代码,它运行得很好,但是如果我在同一次运行中多次运行相同的代码,运行时每次都会变得越来越慢。

如果我将线程数从 4 个增加到 8 个,则每次迭代的减速都会更加剧烈。

每次运行都是完全独立的,我什至将运行时变量设置为 null 以清除旧运行。所以我不知道是什么会减慢它的速度。我一直在使用 Visual VM,它说 .run() 将所有时间都花在“Self Time”或“Thread.init()”上,这没有帮助。

一些代码片段:

for (int r = 0; r < replicateRuns; ++r) {
    startTime = System.nanoTime();
    result = newRuntime.execute();
    result = null;
    System.out.println((System.nanoTime() - startTime) / 1000000);
    total += System.nanoTime() - startTime;
}

    parentThread = this;
    thread = new Thread[numberOfThreads];
    barrier = new CyclicBarrier(numberOfThreads);

    for (int i = 0; i < numberOfThreads; i++) {
        thread[i] = new Thread(new Runtime(parentThread, variation, delta, eta, i,
                numberOfThreads), i + "");
        thread[i].start();
    }

    for (int i = 0; i < numberOfThreads; i++) {
        try {
            thread[i].join();
            thread[i] = null;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

因此,任何关于为什么如果我多次启动 Java 应用程序我会得到不错的结果的线索,但如果我在同一次启动中多次运行它,一切都会变慢,即使据我所见,我正在使一切都无效GC 来清理它。

我正在使用线程局部变量,但是从我读过的内容来看,当线程本身设置为空时,它们都被清除了。

为任何帮助干杯!

编辑1:

感谢所有的帮助。情节变厚了,在我的 Windows 桌面(而不是我的 MacBook)上完全没有问题,即使我增加运行量,每个线程也运行良好,中间没有减慢!在盯着这个看了一天之后,我将在早上的第一件事中再次尝试使用 Eclipse MAT。

关于源代码,我正在使用 MOEAD 的并行版本扩展 MOEA 框架,因此有许多依赖项和类。MOEA 框架你可以在这里找到我的课程的源代码。本质上,迭代被重复调用,直到 numberOfEvaulations 达到一个设定值。

4

2 回答 2

1

我相信大家在这里所说的问题是你没有以正确的方式“停止”你的线程 - 有点说话。

根据我的经验,最好的方法是将状态存储在线程中,在布尔变量中,例如isRunning. 然后在你的循环中你测试isRunning标志的状态,即

//inside the run method
while(isRunning){
//your code goes here
}

这样,在循环的每次迭代中,您都在检查标志的当前状态,因此当您将其设置为“假”时,例如,在您的自定义stop()方法中。循环的下一次迭代将导致线程退出其run方法,从而结束线程的生命。从技术上讲,现在它已经准备好被垃圾收集了。它的内存将在不久的将来某个时候被释放,考虑到在你的代码中的某个地方没有提到这个威胁。

有更多来源展示了这种方法,例如,查看LinkedIn 上的讨论

newRuntime附带说明一下,查看or变量的确切含义、它们的类和继承等实际上很有用result。否则我们只能尝试猜测代码中实际发生的情况。

于 2012-12-17T12:26:30.460 回答
0

您总是在生成新线程并且从不处理它们。如果线程数大于处理器内核数,我们必须切换线程,这可能会降低大约 1000 倍的性能。如果您使用的是 Netbeans IDE,您可以在分析器中查看线程及其状态。

于 2012-12-17T12:38:10.780 回答