面试题答案
一键面试可能导致内存泄漏的不当操作
- 长时间持有 key-value 引用:当 key 或 value 是大对象且在 HashMap 中长时间存在,即使外部不再需要这些对象,但由于 HashMap 对其持有强引用,垃圾回收器无法回收这些对象,从而导致内存泄漏。例如,将一个大的字节数组作为 value 存入 HashMap 且一直不删除该键值对,而外部代码也不再使用这个字节数组对象。
- 使用可变对象作为 key:如果使用可变对象作为 key,并且在将其存入 HashMap 后修改了该对象影响其哈希值或 equals 方法结果的属性。那么后续通过该对象去获取值时可能找不到对应的键值对,同时这个键值对会一直存在于 HashMap 中无法被正确清理,造成内存泄漏。比如,自定义一个类作为 key,该类有一个影响哈希值计算的属性,存入 HashMap 后修改了这个属性。
- 未及时清理不再使用的键值对:当某些键值对不再被外部代码使用,但没有从 HashMap 中移除,这些无用的对象会一直占用内存。比如在一个循环中不断向 HashMap 添加临时使用的键值对,但循环结束后没有清理这些键值对。
避免内存泄漏的方法
- 及时释放引用:当确定不再需要 HashMap 中的某些键值对时,使用
remove(key)
方法将其从 HashMap 中移除。如果是整个 HashMap 不再使用,将其设置为null
,让垃圾回收器可以回收相关内存。 - 使用不可变对象作为 key:优先使用 Java 提供的不可变类(如
String
、Integer
等)作为 key。如果需要自定义 key,确保该类是不可变的,即一旦对象创建,其内部状态不能被修改。 - 定期清理:对于在循环或特定业务逻辑中临时使用的 HashMap,可以在使用完毕后进行清理操作,通过迭代 HashMap 并调用
remove(key)
方法移除不再使用的键值对。