java 中的 java.lang.OutOfMemoryError 错误

标签 java memory out-of-memory

我编写了一个java程序,其中我应该知道两个嵌套的for循环是否可以在4秒内完成它们的执行。如果它们在4秒内完成它们的执行,那么程序应该继续,否则打破循环。我有三个列表 A 、B 和 C,我正在执行一些操作并将其添加到列表 B 中。即使对于列表 A 和 C 的小输入(如 3、6、8、4),我的程序也会抛出 run内存不足错误

我正在使用一个外部 for 循环来计算时间。如果两个 for 循环无法在 4 秒内完成执行,则应终止循环。我正在使用一个计数变量来跟踪 for 循环的执行,即使 for 循环在 4 秒之前完成执行,我也将终止外部 for 循环。
这是我的代码:

while(!(A.isEmpty())){
    ArrayList<Long> B = new ArrayList<>();
    for(long start = System.currentTimeMillis() ; start < System.currentTimeMillis() + 4 * 1000 ; ){
        for(long i : A){
            for(long j : C){
                if(i!=j){
                    B.add(Math.abs(i-j));
                }
            }
            count++;
            if(count==A.size());
                break;
        }
    }
}


这段代码有什么问题?我应该如何使其正确?
谢谢。

最佳答案

我认为这个设计并不是很稳健。我认为您可以考虑在这里使用两个线程,而不是在该循环中调用时间函数:

  1. 线程 A 启动线程 B,并等待 n
  2. 线程 B 进行计算
  3. 当线程 A 唤醒时,它只是检查计算是否完成

或者,你的主线程启动 A 和 B; A 回来告诉你:现在该检查 B 的结果了。

对于你真正的问题;我猜这里有一个贡献者:

B.add(Math.abs(i-j));

你看到 B(顺便说一句,对于数字列表来说,这个名字真的很糟糕!)需要 Long 对象。因此,这个小调用每次迭代至少创建一个 Long 对象。然后你迭代 A 和 C。那里没有任何 sleep 或延迟。这意味着您的代码除了迭代循环和创建新对象来填充 B 列表之外,什么都不做。

现在:您认为 4 秒内会看到多少次循环迭代?足以创建数以百万计的对象?!然后:动态增长的列表很好,但是当 ArrayList 不断超出其容量并需要增长时,您明白这意味着吗?!您知道这意味着创建数组并复制所有值吗?!

我想说的是:仔细看看那里到底做了多少工作;以及您的代码中对原始/引用长/长的装箱量(取消)装箱量。

测试这些想法的一个(也许是简单的方法):将代码从使用长整型列表更改为使用具有长整型值的固定数组。这将产生一个很好的副作用 - 它将迫使您预先考虑您实际想要创建多少个数组槽。在您的解决方案中,您只需不断循环并添加新对象(如上所述;导致 B 列表不断重新容量增加操作)。

关于java 中的 java.lang.OutOfMemoryError 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40074477/

相关文章:

c++ - 为什么成员函数地址与自由函数相距如此远?

java - 使用 Java 读取非常大的文件

linux交换空间从不释放内存

java - 如果 java.lang.OutOfMemoryError 即将发生,请执行

Android/Java 使用 cipher.getOutputSize() 分配字节时内存不足 "OutOfMemoryError"

java - 在 Eclipse 的 Android 项目中保存文本文件的位置

java - 最有效的 Artifact 复制方式?

java - 如何从 rar 存档直接读取所需文件到 InputStream(无需提取整个存档)?

java - 基于矩阵位置[行][列]的Gridview项集

pointers - 原始指针没有产生预期的效果