java - 为什么此代码示例会产生内存泄漏?

标签 java memory-leaks garbage-collection

在大学里,我们得到了以下代码示例,我们被告知,运行这段代码时会发生内存泄漏。该示例应证明这是垃圾收集器无法工作的情况。

就我的面向对象编程而言,唯一能够造成内存泄漏的代码行是

items=Arrays.copyOf(items,2 * size+1); 

documentation说,元素被复制。这是否意味着引用已被复制(因此在堆上创建了另一个条目)或对象本身正在被复制?据我所知,Object 和 Object[] 是作为引用类型实现的。因此,为“items”分配一个新值将允许垃圾收集器发现旧的“item”不再被引用,因此可以被收集。

在我看来,此代码示例不会产生内存泄漏。有人能证明我错了吗? =)

import java.util.Arrays;
public class Foo  
{  
private Object[] items;  
private int size=0;  
private static final int ISIZE=10;

public Foo()  
{  
  items= new Object[ISIZE];  
}  

public void push(final Object o){  
  checkSize();  
  items[size++]=o;  
}  

public Object pop(){  
  if (size==0)  
    throw new ///...  
  return items[--size];  
}  
private void checkSize(){  
  if (items.length==size){  
    items=Arrays.copyOf(items,2 * size+1);  
  }  
}  
}

最佳答案

pop 方法产生内存泄漏。

原因是您只是减少了队列中项目的数量,但实际上并没有将它们从队列中移除。引用保留在数组中。如果您不删除它们,即使生成该对象的代码已执行,垃圾收集器也不会破坏这些对象。

想象一下:

{
    Object o = new Object();
    myQueue.add(o);
}

现在您对该对象只有一个引用 - 数组中的一个。

稍后你会:

{
    myQueue.pop();
}

此 pop 不会删除引用。如果您不删除该引用,垃圾收集器将认为您仍在考虑使用该引用并且该对象很有用。

因此,如果您用 n 个对象填充队列,那么您将持有这些 n 对象的引用。

这是您的老师告诉您的内存泄漏

关于java - 为什么此代码示例会产生内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2843799/

相关文章:

javascript - Ionic(或 Angular )中的内存泄漏?

c++ - 泄漏 sanitizer 是否保证没有内存泄漏?

android - 内存不足内存泄漏问题

java - 高 Perm Generation 和低 Old Generation

c# - 控制台应用程序和单元测试方法之间的不同垃圾收集行为

java - 将从文本文件读取的字符串解析为整数

java - Android Studio - 包含和使用 .so 库

java - eclipse 中的 jax-rs 2.0 要求

image - Go GC 似乎没有收集我未引用的图像加载指针?

java - 使用 Java GregorianCalendar 类打印正确的日期