Threadprogramming,Heap OutOfMemory

时间:2014-06-14 12:39:28

标签: java multithreading out-of-memory

我第一次使用Threads in Java进行编程,所以这里有一个关于Threads的初学者问题。

我的代码:

import java.util.ArrayList;
import java.util.List;

public class CollatzRunner implements Runnable {
private int lastNumber = 0;
private int highestCounter = 0;
private int highestValue = 0;

public void run() {     
    while(this.lastNumber < 1000000) {
        this.lastNumber++;
        Collatz c = new Collatz(lastNumber);
        List<Integer> values = new ArrayList<Integer>();
        while(c.hasNext()) {
            values.add(c.next());
        }

        if(this.highestCounter < values.size()) {
            this.highestCounter = values.size();
            this.highestValue = values.get(0);
        }
        //System.out.println(Thread.currentThread().getName() + ": " + this.lastNumber);
        System.out.println(Thread.currentThread().getName());
    }
}
}

public class CollatzSimulator {
public static void main(String[] args) {
    CollatzRunner runner = new CollatzRunner();

    Thread t1 = new Thread(runner, "Thread-1");
    Thread t2 = new Thread(runner, "Thread-2");
    Thread t3 = new Thread(runner, "Thread-3");
    Thread t4 = new Thread(runner, "Thread-4");
    //Thread t5 = new Thread(runner, "Thread-5");
    //Thread t6 = new Thread(runner, "Thread-6");
    //Thread t7 = new Thread(runner, "Thread-7");
    //Thread t8 = new Thread(runner, "Thread-8");

    t1.start();
    t2.start();
    t3.start();
    t4.start();
    //t5.start();
    //t6.start();
    //t7.start();
    //t8.start();

    System.out.println("bla");
}   
}

运行此代码时几乎立即得到OutOfMemoryError:堆空间。所以我怀疑这里有一个非常重要的内存泄漏。问题是我没有这方面的经验,因此我在这个网站上提问。

到目前为止我尝试过的事情: - 堆空间转储文件(生成5秒内800MB) - 尝试将Collat​​z实例设置为null后使用它来终止引用,希望垃圾收集器释放堆空间。

我的程序只是一个小类Collat​​z,它为给定的数字生成collat​​zsequence,我想使用线程生成0&lt; 0的所有collat​​zsequenzes。 n&lt;百万。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

我很确定这个问题可以在这里找到:

List<Integer> values = new ArrayList<Integer>();
while(c.hasNext()) {
    values.add(c.next());
}

根据我的理解,Collat​​z序列可以非常长。 c.next()做的是计算序列的下一个成员,它几乎不使用任何空间。但是将所有序列成员连接到列表中会占用大量空间。你创建的线程越多,你就越早碰到这个障碍。

如果您没有为堆分配巨大空间的选项,我很确定唯一的选择是编写values的一部分一旦超过特定长度就会列出文件(无论如何你都必须输出它)。但是,对于所有I / O,多线程的使用将毫无意义

答案 1 :(得分:0)

为了确定给定起始值的Collat​​z序列的长度:不要存储序列,只需计算Collat​​z返回的值的数量:

Collatz c = new Collatz(lastNumber);
int length = 0;
while(c.hasNext()) {
    length++;
}

if(this.highestCounter < length) {
    this.highestCounter = length;
    this.highestValue = lastNumber;
}

<强>后来

在阅读了“线程”挑战之后:如果您的计算机具有多个核心,那么通过并行运行多个线程(核心数)来尝试搜索最长达1M的Collat​​z序列是有意义的, 但不使用相同的代码。添加参数startValue并增加到Collat​​z运行器并为每次迭代添加此项,以便第一个线程(例如四个)计算1,5,9,...第二个2,6,10,......第三个3 ,7,11,......和第四个4,8,12,......