Java循环创建对象的堆内存回收时机及变量声明影响疑问
Java循环中对象的内存回收问题
问题1解答
Java不会在for循环结束后立刻将对象从堆中移除。对象的回收时机由JVM的垃圾回收(GC)机制决定:只有当对象没有任何可达的强引用时,才会被标记为可回收对象,等待GC线程运行时释放其占用的堆内存。循环结束只是局部变量的作用域结束,但如果对象还被其他存活的引用(比如集合)持有,就不会被回收。
问题2解答
先明确核心前提:你在循环中将每个OrderItem对象都添加到了orderItemList中,这个列表会持有所有对象的强引用——这是决定对象是否被回收的关键,和item变量的声明位置无关。
代码示例1分析
for (int i = 0; i < arr.length; i++) { OrderItem item = new OrderItem(); item.setProduct(product); item.setQuantity(entry.getValue()); orderItemList.add(item); }
每次循环都会创建一个局部变量item,它指向新的OrderItem对象。循环结束后,这些item局部变量的作用域消失,但所有OrderItem对象都被orderItemList持有引用,只要orderItemList本身还处于可达状态(比如方法未结束、其他地方还能访问这个列表),这些对象就不会被回收,和栈中是否存在多个局部变量无关。
代码示例2分析
OrderItem item; for (int i = 0; i < arr.length; i++) { item = new OrderItem(); item.setProduct(someValue); item.setQuantity(someValue); orderItemList.add(item); }
你的理解是错误的:虽然栈中只有一个item变量,每次迭代指向新对象,但前一次迭代创建的对象已经被添加到orderItemList中,列表依然持有它的引用,所以这些对象仍然是可达的,不会被堆内存回收。只有当orderItemList本身失去所有引用(比如方法执行完毕,列表出了作用域),里面的OrderItem对象才会变成不可达,等待GC回收。
内容的提问来源于stack exchange,提问作者Дмитрий Каспорский
相关产品推荐
相关产品推荐

