日期:2014-05-20  浏览次数:20782 次

关于JVM内存清理的问题
程序中存在内存泄漏,用Jprobe分析时发现一个问题

程序有个静态的哈希表:
public static HashMap<String, StudentVO> ccHashMap = new HashMap<String, StudentVO>();

我在ccHashMap中put了1000条记录,然后挨个remove掉。

我用Jprobe观察发现JVM中一直存在1000条StudentVO,Heap Count:1000。

尝试ccHashMap每次remove掉一条记录后调用System.gc();再用Jprobe观察就没有了。

请教这个地方是导致内存泄漏的地方吗?StudentVO为什么没有被自动回收掉?

------解决方案--------------------
同学对JVM的内存回收策略不太熟悉啊?建议可以Google了解下。

JVM并不实时回收内存,这样效率太低,类似你这个例子,如果你remove一千条记录,岂不是JVM要执行一千次回收?

所以JVM的回收策略基本是按需,也就是内存不够的情况下,再执行自动执行GC。



所以我认为不是这个地方导致内存泄漏。另外你也没必要主动调用System.gc();。
如果泄漏,必然是因为某些对象的引用没有被彻底释放。
------解决方案--------------------
因为垃圾回收是系统内部线程(垃圾管理器)管理的,执行remove后不保证垃圾回收一定会马上被执行(垃圾管理器有Timer来定时回收垃圾的)
调用gc也不保证垃圾回收一定马上执行,不过gc会通知垃圾回收管理器有垃圾可以回收了,所以垃圾回收管理器可能会在CPU空闲时去回收系统垃圾


------解决方案--------------------
垃圾回收器会定时对内存进行清理的,并不是实时的。