当我从Java中删除ArrayList中的1个对象时。接下来发生什么?

时间:2017-02-25 08:49:55

标签: java arraylist memory-management reference internal

我有一个像这样简单的arraylist: ..

ArrayList<SP> sps = new ArrayList<SP>();
sps.add(new SP("1"));
sps.add(new SP("2"));
sps.add(new SP("3"));

.. 当我从该列表中删除1个对象时。 接下来发生什么? 该列表只删除该对象的引用 然后对象自动释放该内存区域 (因为没有引用该对象的内存) 要么 该对象是由该列表直接从该内存区域释放的吗?

P / s:抱歉我的英语不好。

4 个答案:

答案 0 :(得分:10)

如果调用ArrayList.remove(),则从列表中删除给定索引处的元素(并且跟随它的所有元素向下移动一个索引)。对象本身仍然存在,尚未释放任何内存。

如果在从列表中删除对象后,应用程序中没有对该对象的剩余引用 - 这意味着它现在已被程序使用 - Garbage Collector将自动释放与该对象关联的内存,它可以重复使用。

答案 1 :(得分:4)

ArrayList和删除的对象都会发生一些事情。

当调用ArrayList.remove()时,它确实从ArrayList中删除了对该对象的引用。此外,继续删除元素的内容向下移动一次。

如果没有其他对该对象的引用,则现在可以在名为Garbage Collection的自动过程中释放为该对象分配的内存

示例:

ArrayList<Integer> example = otherArrayList; // {2,3,10,6}
example.remove(1);                           // Remove second element
System.out.println(example.toString());

> [2, 10, 6] 
// The space to which '3' is allocated to is now eligible for GC

不符合GC条件的对象示例:

ArrayList<Integer> example = otherArrayList; // {2,3,10,6}
int ref = example.get(1);                    // '3' is assigned to ref
example.remove(1);                           // Remove second element
System.out.println(example.toString());
System.out.print(ref);                      

> [2, 10, 6] 
> 3

/* Java is based on pass-by-value, but it passes references 
   when we pass existing object values. Which means the
   address space allocated for ref (and formerly example.get(1)) 
   is ineligible for GC.
*/ 

答案 2 :(得分:1)

  

该列表只删除该对象的引用,然后对象自动   释放该内存区域(因为没有引用该内存   该对象)或该对象直接从该内存中释放   区域列表?

JVM不能以这种方式工作。

1)当一个对象被内存中的活动对象引用时,它不符合GC的条件。

2)即使内存中的活动对象不再引用对象,内存释放也不是自动的。
只有在垃圾收集器执行Gargbage集合(次要或完整)时才会释放它。

答案 3 :(得分:0)

ArrayList<SP> sps = new ArrayList<SP>();

这意味着,ArrayList类型为SP,此ArrayList的每个索引都是SP的一种,简而言之,它将是一个参考变量SP

现在,当您调用new SP("1");时,将创建object to SP,构造函数将返回该对象的引用。但是这里没有分配给new SP("1");的兼容引用变量。因此无法再访问该对象。

但是在您的ArrayList中(对于相同的语句),将有一个引用来接受来自constructor of SP的返回。因此,当您从列表中删除该对象时,它将丢失其唯一的引用,并且有资格进行垃圾回收。

参考:Calling methods on reference variable vs Calling methods on a new object