clear()复用原对象,内存地址不变且底层数组容量保留;重新赋值创建新对象,旧对象无引用时才可被回收;典型陷阱是多次add同一clear的map导致数据覆盖。

Map 的 clear() 方法不会销毁对象,只是清空键值对;而重新赋值(如 map = new HashMap())会创建新对象,原对象若无其他引用则可被回收。二者内存行为差异明显,关键在“复用”还是“替换”。
clear():复用对象,不释放底层内存
调用 clear() 后:
- Map 实例本身仍在堆中,内存地址不变(
System.identityHashCode(map)不变) - 内部数组(如 HashMap 的 table)元素被置为
null,size 归零,但数组容量(capacity)保留 - 原有对象仍持有强引用,JVM 不会回收它,即使内容为空
- 适合循环中反复填充的场景,避免频繁分配/回收内存开销
重新赋值:生成新对象,旧对象可能待回收
执行 map = new HashMap() 后:
- 新建一个 Map 实例,拥有全新内存地址和初始容量(通常是 16)
- 原 Map 对象若不再被任何变量、集合或闭包引用,就符合垃圾回收条件
- 但若该 Map 曾被放入 List、作为字段保存、或被监听器持有,则仍存活,造成内存滞留
- 每次创建都涉及对象分配和初始化,高频调用可能增加 GC 压力
典型陷阱:List 存了同一个 clear 的 Map
常见错误写法:
Map<string object> map = new HashMap();
List<map object>> list = new ArrayList();
for (int i = 0; i
<p>结果:list 中三个元素指向同一 Map,最终只保留最后一次 put 的数据(<code>{"id": 2}</code>),且三次 clear 都作用于同一个对象。</p>
<p>正确做法是每次新建:</p>
<pre class="brush:php;toolbar:false;">for (int i = 0; i map = new HashMap(); // 新对象
map.put("id", i);
list.add(map);
}
内存优化建议
根据使用场景选择:
- 需长期复用、且确定容量稳定 → 用
clear(),可配合预设初始容量(new HashMap(128))减少扩容 - 每次数据逻辑独立、避免状态干扰 → 用
new HashMap(),语义清晰、线程安全更易保障 - 担心内存泄漏(尤其缓存类场景)→ 清空后显式置
map = null(仅当确认无其他引用时有效) - 大 Map 需彻底释放内存(如临时解析后丢弃)→ 不仅
clear(),还要确保无外部引用,必要时触发 GC(不推荐主动调用,应靠设计规避)











