关于’new’关键字的Java内存问题

如果您运行以下代码会发生什么?

while (true) { String x = new String("ABC"); } 

在记忆方面?

字符串x是在堆栈上还是在堆上分配的? 由于内存溢出,程序最终会崩溃,还是垃圾收集会阻止它? new关键字是否始终在堆上创建对象? 什么时候在堆栈上创建对象?

谢谢!

字符串x是在堆栈上还是在堆上分配的?

x不是String 。 它是对String的引用。 引用是一个局部变量,因此在堆栈上。 String是一个对象,因此在堆上。

由于内存溢出,程序最终是否会崩溃

可能不是。

或垃圾收集会阻止吗?

这应该。

new关键字是否始终在堆上创建对象?

是。

什么时候在堆栈上创建对象?

永远……除非JVM决定它无法逃避当前范围,因此决定这样做。

使用new,yes,将对象放在堆上。 任何线程都无法访问的对象可以被垃圾回收。 是否内存不足取决于程序使用的数据大小,如果你擅长“释放”对象,你就不再需要了(想想:内存泄漏很糟糕)。

在您的示例中,您将像疯了一样运行垃圾收集器,我认为这是您打算演示的内容。

局部变量在堆栈上。

理论上, new在Heap上创建,并且在堆栈上创建非对象(即intchar等)。 唯一的例外是afaik,也是在堆栈上创建的字符串。 在实践中,许多现代JVM的JIT编译器将看到,在某些情况下,可以在堆栈上创建使用new创建的对象(例如,未在当前函数之外引用的本地对象)。

垃圾收集器将为您处理释放,这是它的目的,但是如果您同时创建并保留对太多对象的引用,则当然可能会耗尽内存(尝试创建一个包含十亿字符串的列表,例)。