java中的java.lang.OutOfMemoryError错误

java中的java.lang.OutOfMemoryError错误,java,memory,out-of-memory,Java,Memory,Out Of Memory,我编写了一个java程序,其中我应该知道,如果两个嵌套的for循环可以在4秒内完成它们的执行,或者如果它们在4秒内完成它们的执行,那么程序应该继续,否则会中断循环。我有三个列表A、B和C,我正在执行一些操作并将其添加到列表B中。即使对于列表A和C的小输入,如3、6、8、4,我的程序也会抛出内存不足错误 我使用一个外部for循环来计算时间。如果两个for循环无法在4秒内完成其执行,则应终止该循环。我使用一个计数变量来跟踪for循环的执行,即使for循环在我终止外部for循环的4秒钟之前完成了它们的

我编写了一个java程序,其中我应该知道,如果两个嵌套的for循环可以在4秒内完成它们的执行,或者如果它们在4秒内完成它们的执行,那么程序应该继续,否则会中断循环。我有三个列表A、B和C,我正在执行一些操作并将其添加到列表B中。即使对于列表A和C的小输入,如3、6、8、4,我的程序也会抛出内存不足错误 我使用一个外部for循环来计算时间。如果两个for循环无法在4秒内完成其执行,则应终止该循环。我使用一个计数变量来跟踪for循环的执行,即使for循环在我终止外部for循环的4秒钟之前完成了它们的执行。
这是我的密码:

while(!(A.isEmpty()){
ArrayList B=新的ArrayList();
用于(长启动=System.currentTimeMillis();启动

这个代码有什么问题?我应该如何更正它?

谢谢。

我认为这种设计不是很坚固。我认为您可以在这里使用两个线程,而不是在该循环中调用time函数:

  • 线程A踢线程B,并等待n秒
  • 线程B进行计算
  • 当线程A醒来时,它只是检查计算是否完成
  • 或者,你的主线程踢A和B;A回来告诉你:现在是时候检查B的结果了

    和你真正的问题;我想这里有一个贡献者:

    B.add(Math.abs(i-j));
    
    你会看到B(对于一个数字列表来说真是个坏名字,顺便说一句!)taks长对象。所以,那个小小的调用在每次迭代中至少创建一个长对象。在A和C上迭代,没有任何睡眠或延迟。这意味着您的代码除了迭代循环和创建新对象以填充B列表之外,什么都不做

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

    我想说的是:仔细看看那里到底有多少工作在进行;以及代码中有多少(未)装箱的基元/引用长/长


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

    您有一个无限循环,
    while(!(A.isEmpty))
    总是正确的,因为在for循环中,您从未从A中删除任何元素。这将导致您向B添加无限多的元素,因为
    B.add(Math.abs(i-j))

    语句
    而(!(A.isEmpty())
    将运行一个无限循环,导致B被无限次实例化


    结果导致OutOfMemoryError

    这是一个无限循环,因为您没有在循环中编写
    start++
    或任何类似的内容。我想,最终你会耗尽内存。即使我开始递增,仍然得不到输出。我很困惑,这是检查嵌套for循环是否能在4秒钟内完成其执行的最佳方法吗?您的问题是您把事情搞混了。你想A)计算某物B)测量某个时间。正如我在回答中所概述的,你应该把这两个问题分开!在外部for循环的测试条件下,
    start
    的值将始终小于
    System.currentTimeMillis()
    返回的值。整个模式看起来很糟糕,但如果您坚持使用它,请尝试创建一个
    end
    时间,即当前时间加上四秒,然后将for循环测试条件更改为
    System.currentTimeMillis()
    。如果我理解正确,您要做的是持续向ArrayList添加内容4秒钟,然后停止?这有什么意义?你可以在4秒内添加很多元素,当然,除非你有很多内存,否则你将耗尽存储它们的内存这并不是导致内存不足异常的原因,因为每次外部循环运行时都会重新定义B,这样它就不会向B添加无限元素。假设gc正在执行其工作,则在无限循环中重新创建局部变量不会造成内存不足exception@LucasKot-Zaniewski这完全取决于每个循环迭代创建了多少垃圾。你看,如果你的CPU在这些循环中全速运行,每个循环只创建一个应该被“垃圾”的对象。。。世界上没有一个GC能跟上这里的步伐。做GC需要时间。你没有时间,当你的代码除了创建垃圾外什么都不做!。。。而且gc不会运行,或者至少不能依赖于运行,一致地或持续地运行。我当前运行的是一个无限循环,只声明了一个ArrayList变量(在每次迭代中向它添加100个字符串)稍后再参考它,看看GC需要多长时间才能跟上…我怀疑这将是一段相当长的时间,但我会根据结果进行更新。不管怎样都是
    B.add(Math.abs(i-j));