最近在写web程序,根据需要写了一个缓存,用HashMap做的,大概如下
这个web程序run了两天没有任何请求,两条后我去操作这个缓存,其中的数据还在(缓存策略不会清除数据),当然如果不在的话就出问题了。
我的问题是为什么这个cache对象不会被JVM垃圾回收掉呢,是不是类对象不会轻易被回收呢,像method方法中的i局部变量是不是用完过后会马上被回收掉呢?
看过JVM相关的垃圾回收机制,当时感觉懂了,不过一看具体问题感觉还是不明白
首先说一下什么是垃圾? 一般来说,所有指向对象的引用都已失效,不可能再有程序能调用到这个对象,那么这个对象就成了垃圾,应该被回收。 而Java通常是基于GC Roots的可达性来判断对象的引用是否失效的。 因此, 基于你这个问题, 弄清楚了GC Roots可达行即可解决。
GC Roots有一些几类:
上面楼主例子中的cache属于第一类:虚拟机栈中的引用对象, 所有它不是垃圾, 即使发生GC 也不会被回收
而方法中的i是一个局部变量, 方执行结束后就处于GC Roots不可达的状态,它被当做的垃圾, 但是否要被回收还要看是否发生了GC。
1.这里的i是个primitive。他应该是存在栈上的,不在堆上。所以木有垃圾回收一说(当然,方法一返回,i内存位置的那个数据就不可靠了,可以说被“回收”了)。
2.没大看懂那个cache的问题。一般情况下,JVM在堆空间不够用了的时候才会开始回收。如果你的堆的最大空间(Xmx)设置的非常大,则JVM通常会扩展堆大小,而不是回收垃圾。因为回收垃圾总是要耗CPU的。这终究跟JVM的实现细节有关。
3.垃圾回收是这样的,如果你的程序没有任何办法访问到那个对象了,那么这个对象就可以被回收了。若你创建了一个XXCache对象,他内部就包含对那个HashMap的引用,如果你还能访问那个类别为XXCache的对象,这就说明你可以访问那个HashMap,JVM就不会贸然把cache给回收掉。
如果你的程序访问不到那个XXCache对象了,而且也没有对cache的其他引用。那cache就随时有可能被回收。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。