开发者社区> 问答> 正文

关于JVM垃圾回收

最近在写web程序,根据需要写了一个缓存,用HashMap做的,大概如下
screenshot
这个web程序run了两天没有任何请求,两条后我去操作这个缓存,其中的数据还在(缓存策略不会清除数据),当然如果不在的话就出问题了。
我的问题是为什么这个cache对象不会被JVM垃圾回收掉呢,是不是类对象不会轻易被回收呢,像method方法中的i局部变量是不是用完过后会马上被回收掉呢?
看过JVM相关的垃圾回收机制,当时感觉懂了,不过一看具体问题感觉还是不明白

展开
收起
蛮大人123 2016-02-29 17:28:39 3239 0
4 条回答
写回答
取消 提交回答
  • https://www.cnblogs.com/cielosun/p/6674431.html
    2019-07-17 18:50:40
    赞同 展开评论 打赏
  • 建议看 深入理解java虚拟 这本书,对系统学习有帮助
    2019-07-17 18:50:40
    赞同 展开评论 打赏
  • 首先说一下什么是垃圾? 一般来说,所有指向对象的引用都已失效,不可能再有程序能调用到这个对象,那么这个对象就成了垃圾,应该被回收。 而Java通常是基于GC Roots的可达性来判断对象的引用是否失效的。 因此, 基于你这个问题, 弄清楚了GC Roots可达行即可解决。
    GC Roots有一些几类:

    1. 虚拟机栈中的引用对象
    2. 方法区中类静态属性引用的对象
    3. 方法区中常量引用对象
    4. 本地方法栈中JNI引用对象

    上面楼主例子中的cache属于第一类:虚拟机栈中的引用对象, 所有它不是垃圾, 即使发生GC 也不会被回收
    而方法中的i是一个局部变量, 方执行结束后就处于GC Roots不可达的状态,它被当做的垃圾, 但是否要被回收还要看是否发生了GC。

    2019-07-17 18:50:40
    赞同 展开评论 打赏
  • 我说我不帅他们就打我,还说我虚伪

    1.这里的i是个primitive。他应该是存在栈上的,不在堆上。所以木有垃圾回收一说(当然,方法一返回,i内存位置的那个数据就不可靠了,可以说被“回收”了)。
    2.没大看懂那个cache的问题。一般情况下,JVM在堆空间不够用了的时候才会开始回收。如果你的堆的最大空间(Xmx)设置的非常大,则JVM通常会扩展堆大小,而不是回收垃圾。因为回收垃圾总是要耗CPU的。这终究跟JVM的实现细节有关。
    3.垃圾回收是这样的,如果你的程序没有任何办法访问到那个对象了,那么这个对象就可以被回收了。若你创建了一个XXCache对象,他内部就包含对那个HashMap的引用,如果你还能访问那个类别为XXCache的对象,这就说明你可以访问那个HashMap,JVM就不会贸然把cache给回收掉。
    如果你的程序访问不到那个XXCache对象了,而且也没有对cache的其他引用。那cache就随时有可能被回收。

    2019-07-17 18:50:40
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
JVM实战 立即下载
JVM的GC 立即下载
基于JVM的脚本语言开发、运用实践 立即下载