如果我将对象添加到
HashMap
中,然后在不再需要它们时只调用remove
方法,是否保证它们占用的资源会被释放(假设没有其他引用指向它们)?HashMap
中,然后在不再需要它们时只调用remove
方法,是否保证它们占用的资源会被释放(假设没有其他引用指向它们)?HashMap
的条目存储在数组中。如果您删除一个条目,则相关的数组位置将变为null
。因此,hashMap
不再引用已删除的value
对象。
然后,垃圾回收的普通规则将应用于value
对象。
验证的简单代码。
public class REPL7 {
public static void main(String[] args) throws Exception {
Map<String, Foo> map = new HashMap();
map.put("one", new Foo("foo one"));
map.put("two", new Foo("foo two"));
// make the backing array accessible
Field field = map.getClass().getDeclaredField("table");
field.setAccessible(true);
Object[] obj = (Object[]) field.get(map);
// two references to Foo objects will be shown
System.out.println("obj = " + Arrays.toString(obj));
map.remove("one");
// only one reference to a Foo object will eb shown
System.out.println("obj = " + Arrays.toString(obj));
}
}
class Foo {
String marker;
Foo(String marker) {
this.marker = marker;
}
@Override
public String toString() {
return "Foo{" + marker + '}';
}
}
Map < int, Object > map = new HashMap < int, Object > ();
CustomObject x = new CustomObject();
map.put(1, x);
map.remove(1);
//you still have access to x
map.put(x); x = null; map.remove(x);
- Jordi Castillax==null
时,map.remove(x)
将无法按预期工作。 - ivan.mylyanykHashMap
中调用remove
方法时,它只会删除其ID和值,而不是您创建的对象。我将对象放入HashMap中,然后将它们移除。
放置在HashMap中的对象的类:
public class ObjectTestsub {
String name;
public ObjectTestsub(String name) {
this.name = name;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("ObjectTestsub: " + name + " is garbage collected");
}
}
主函数:
public class ObjectTest {
HashMap<String, ObjectTestsub> map;
public static void main(String[] args) {
var map = new HashMap<String, ObjectTestsub>();
for (int i = 0; i < 1000000; i++) {
map.put("Obj" + i, new ObjectTestsub("first " + i));
map.remove("Obj" + i);
}
}
}
输出:
....
ObjectTestsub: first 822685 is garbage collected
ObjectTestsub: first 822684 is garbage collected
ObjectTestsub: first 822683 is garbage collected
ObjectTestsub: first 822682 is garbage collected
....
ObjectTestsub: first 822677 is garbage collected
ObjectTestsub: first 822676 is garbage collected
ObjectTestsub: first 822675 is garbage collected
ObjectTestsub: first 822674 is garbage collected
"被销毁"的对象数量是Java垃圾回收器考虑的因素。 这里重要的是一些对象被回收(因此已被释放)。 一切都进行得很好。
现在我改变了代码:
public class ObjectTest {
HashMap<String, ObjectTestsub> map;
public static void main(String[] args) {
var map = new HashMap<String, ObjectTestsub>();
for (int i = 0; i < 1000000; i++) {
map.put("Obj" + i, new ObjectTestsub("first " + i));
}
System.out.println("first part has DONE! size: " + map.size());
for (int i = 0; i < 1000000; i++) {
map.remove("Obj" + i);
}
System.out.println("second part has DONE! size: " + map.size());
}
}
这里是输出:
first part has DONE! size: 1000000
second part has DONE! size: 0
"ObjectTestsub"对象的“析构函数”不再有任何消息。 看起来它们还没有被释放...
问题出在哪里? :/
WeakHashMap
ж›үд»ӘHashMap
гЂ‚ - Prashantmap.put("key", new SomeClass());
和map.remove("key")
之后,SomeClass
的对象是否有资格被垃圾收集器删除。 - SubOptimal