如果您运行以下代码会发生什么..
while (true) {
String x = new String("ABC");
}
在内存方面?
String x 是分配在栈上还是堆上?程序最终会因为内存溢出而崩溃,还是垃圾收集会阻止这种情况?new 关键字是否总是在堆上创建对象?什么时候在堆栈上创建对象?
谢谢!
如果您运行以下代码会发生什么..
while (true) {
String x = new String("ABC");
}
在内存方面?
String x 是分配在栈上还是堆上?程序最终会因为内存溢出而崩溃,还是垃圾收集会阻止这种情况?new 关键字是否总是在堆上创建对象?什么时候在堆栈上创建对象?
谢谢!
String x 是分配在栈上还是堆上?
x
不是一个String
。它是对 a 的引用String
。引用是一个局部变量,所以在堆栈上。是String
一个对象,所以在堆上。
程序最终会因为内存溢出而崩溃吗
可能不是。
还是垃圾收集会阻止这种情况?
它应该。
new 关键字是否总是在堆上创建对象?
是的。
什么时候在堆栈上创建对象?
从不……除非 JVM 决定它不能逃脱当前范围并因此决定这样做。
是的,使用 new 将对象放在堆上。任何线程都不能再访问的对象可以被垃圾回收。是否内存不足取决于程序使用的数据大小,如果您擅长“释放”不再需要的对象(想想:内存泄漏是不好的)。
在您的示例中,您将疯狂地运行垃圾收集器,我认为这就是您要演示的内容。
局部变量进入堆栈。
理论上,在堆上创建new
,非对象(即int
s、char
s等)在栈上创建。唯一的例外 afaik 是在堆栈上创建的字符串。在实践中,许多现代 JVM 的 JIT 编译器会发现,在某些情况下,new
可以在堆栈上创建使用创建的对象(例如,在当前函数之外未引用的本地对象)。
垃圾收集器将为您处理释放,这就是它的目的,但是如果您同时创建并保留太多对象的引用,当然您可能会耗尽内存(尝试创建一个包含十亿个字符串的列表,例如例子)。