我第一次使用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) - 尝试将Collatz实例设置为null后使用它来终止引用,希望垃圾收集器释放堆空间。
我的程序只是一个小类Collatz,它为给定的数字生成collatzsequence,我想使用线程生成0&lt; 0的所有collatzsequenzes。 n&lt;百万。
感谢您的帮助!
答案 0 :(得分:0)
我很确定这个问题可以在这里找到:
List<Integer> values = new ArrayList<Integer>();
while(c.hasNext()) {
values.add(c.next());
}
根据我的理解,Collatz序列可以非常长。 c.next()
做的是计算序列的下一个成员,它几乎不使用任何空间。但是将所有序列成员连接到列表中会占用大量空间。你创建的线程越多,你就越早碰到这个障碍。
如果您没有为堆分配巨大空间的选项,我很确定唯一的选择是编写values
的一部分一旦超过特定长度就会列出文件(无论如何你都必须输出它)。但是,对于所有I / O,多线程的使用将毫无意义
答案 1 :(得分:0)
为了确定给定起始值的Collatz序列的长度:不要存储序列,只需计算Collatz返回的值的数量:
Collatz c = new Collatz(lastNumber);
int length = 0;
while(c.hasNext()) {
length++;
}
if(this.highestCounter < length) {
this.highestCounter = length;
this.highestValue = lastNumber;
}
<强>后来强>
在阅读了“线程”挑战之后:如果您的计算机具有多个核心,那么通过并行运行多个线程(核心数)来尝试搜索最长达1M的Collatz序列是有意义的, 但不使用相同的代码。添加参数startValue并增加到Collatz运行器并为每次迭代添加此项,以便第一个线程(例如四个)计算1,5,9,...第二个2,6,10,......第三个3 ,7,11,......和第四个4,8,12,......