3

我阅读了有关无限循环的信息,发现在某些语言中,当堆栈溢出或达到分配的最大内存时它会停止。其他人将永远循环,具体取决于程序和语言的类型。我的问题是,java无限循环会停止吗?我只是好奇,因为 java 有一个垃圾收集器,它在内存泄漏时重用内存,以防达到分配的最大内存和堆栈溢出。

另外,这种无限循环会停止吗?

for( ; ; ){}
4

3 回答 3

7

我的问题是,java无限循环会停止吗?

有些会,有些不会。这取决于如何实现循环。

基本上,您确定在其他语言中停止的情况也可能在 Java 中停止......取决于您如何编码。

  • 通过无限递归实现的循环将发生堆栈溢出。这在 Java 中比在某些语言中更容易“实现”。(没有尾调用优化。)

  • 如果循环重复分配仍然可访问的对象,则会发生堆溢出......因此 GC 无法回收它们。

(还有其他各种方式可以终止看似无限的循环。)

我只是好奇,因为 java 有一个垃圾收集器,它在内存泄漏时重用内存,以防达到分配的最大内存和堆栈溢出。

垃圾收集器回收无法访问的对象,但无法回收可访问的对象(即程序将来可以使用的对象)。

垃圾收集器不处理堆栈内存,因此与堆栈溢出故障无关。

另外,这种无限循环会停止吗?

不。


严格来说,任何循环都不是无限的,如果它停止......出于任何原因。这包括堆栈溢出或内存耗尽等原因。

但即使是无限循环也不是真正的无限。最终用户将终止循环程序,电源将失效,硬件将被报废......或类似的事情。

于 2013-09-18T01:07:04.180 回答
3

无限循环不会停止,没有其他原因导致整个事情崩溃:-)

这通常是资源短缺,无论是无限递归情况下的堆栈空间,还是内存不足,因为您在循环中分配了一些(而不是释放它)。

垃圾收集只会扔掉垃圾。如果您的变量仍然可以访问内存,则不会将其视为垃圾。

换句话说,如果您的无限循环每次都将一个元素添加到链表的末尾(并且您不会失去对头部的访问权限),那么这些节点都不会被垃圾收集,您最终会用完记忆。

你的那个特定循环:

for (;;) {}

实际上不会停止,因为它没有使用任何资源。当然,您可以终止该进程,或者您可能有一个使用资源的单独线程。这两个(和其他事件)都可能导致循环停止,但它们都在该循环的控制之外。

于 2013-09-18T01:06:27.833 回答
2

如果内存在循环中增长,无限循环可能会因为内存而停止。在这种情况下,没有内存增长。

但是,如果您在循环的每次迭代中创建一些新的重对象,那么它最终会由于内存限制异常而停止。

于 2013-09-18T01:07:40.323 回答