Content-Length: 305875 | pFad | http://github.com/bootsrc/java-interview/commit/adc688f2bc26aab04f7ae7f1c36f4f5cfae23d0f

7E HashMap内存溢出 · bootsrc/java-interview@adc688f · GitHub
Skip to content

Commit adc688f

Browse files
committed
HashMap内存溢出
1 parent ff5a6e7 commit adc688f

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

readme/hashmap-memory-leak.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
当Key为复杂类型(自定义对象)的时候,如果map.put(obj, value)后
44
如果修改了obj中的某些字段值,而且这这个字段会导致obj.hashCode()发送变化的。就必定导致内存泄漏。
5+
因为Node数据的存放地址没变,但是里面的key变了。
6+
7+
导致后面get()的时候,通过新的hashCode找到的新位置那里是空的。
58

69
结果是后面如论是进行map.get(obj), remove(obj), containsKey(obj)都没有意义。
710
map.get(obj)==null, remove(obj)操作无效, containsKey(obj)==false
@@ -175,4 +178,19 @@ class Person {
175178
}
176179
}
177180

181+
```
182+
183+
重点看溢出点的注释
184+
```java
185+
p.setName("lisi"); // 这里造成p2这个key的数据内存泄漏。导致后面无法被删除掉
186+
// p.setName("lisi")后, 这个Node存放的Entry的未知不变,但是,里面Node里面的Key的name变里,导致key的hashCode()变了。
187+
// 后面通过map.get(p)去检索数据的时候,p.hashCode()变了,经过hash计算后得到位置是Y(Y此时为空)
188+
// 所以这时候map.get(p)返回null, map.containsKey(p)返回false
189+
// 所以位置X处的Node数据已经无法进行get() ,put(),containsKey(), remove()的操作了
190+
// 这个内存因为被HashMap引用,也无法GC,
191+
// 这快内存不能被删也不能鄂博查询,也不能被GC回收,称之为内存泄漏(memory leak)
192+
// 这才几个字节的内存泄漏,还不会出事故, 大量的内存泄漏,会浪费很多内存,降低系统性能。最终浪费大量的堆内存,
193+
// 最终导致内存溢出(Out of memory, OutOfMemoryException, 或者报错Heap Space...)
194+
// 结论: 大量的内存泄漏会最终导致内存溢出。 如果出现了内存溢出的报错,我们可以去查看代码,是否有内存泄漏,
195+
// 或者到map里查看是否有一些无意义的垃圾数据(极有可能是内存溢出的数据)
178196
```

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/bootsrc/java-interview/commit/adc688f2bc26aab04f7ae7f1c36f4f5cfae23d0f

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy