论垃圾回收器对java堆和方法区的回收 ——《深入理解JAVA虚拟机》

(1)对于内存里面的运行时数据区域,哪些需要回收?哪些不需要?怎么分?

区分:

        1)内存分配和回收都具有确定性,随着方法结束或者线程结束被回收-->随线程生死的区域,以及栈中的栈帧

        例如:程序计数器(Program Counter)、虚拟机栈(Virtual Machine Stack)、本地方法栈(Native Method Stack)、栈帧(Stack Frame)

        2)内存的分配和回收都是动态的,即它可能是程序开始运行才知道创建哪些对象,接口有多个实现类、方法有多个分支等,这一部分在java里面是被多个线程共享的内存区域。

        例如:java堆和方法区

(2)回收什么样子的数据?

        不能再被任何途径使用的对象

(3)怎么判断对象不再被使用?即怎么判断对象“死去”?

        判断对象是否“死去”的算法?

        1)引用计数算法(Reference Counting,注意存在场景)

        利用引用计数器,被引用+1,引用失效-1,为0时就是不可能再被使用 -->场景为python、一些游戏脚本等 

        注意:主流java虚拟机不选用该算法来管理内存,主要是存在了对象直接互相引用,但是两者的引用计数不为0而无法回收的情况

        2)可达性分析算法((Reachability Analysis)

        以“GC Roots”为起始点,从这些节点开始向下搜索,当对象到GC Roots没有任何引用链相连则不可用,即可回收

         java GC Roots: 虚拟机栈引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象(例如字符串常量)、本地方法栈中JNI引用的对象(就是native关键字修饰的方法)等 

(4)怎么收集?垃圾收集算法?

        1)标记-清除 算法(Mark-Sweep)

       标记要回收,标记完统一回收

        缺点: 效率低,标记清除后空间不连续(内存碎片,当需要分配较大对象时,因无法找到足够的连续内存而需要提前触发另一次垃圾回收?)

        2)复制算法(Copying)

       内存平分成两块,用的时候只用一块,用完了就把还活着的复制到另一块上,再把已使用过的空间一次性清理掉。(有其他优化的内存划分方法)

        缺点:占内存

        3)标记-整理算法(Mark-Compact)

        标记要回收,让所有存活对象都向一端移动,直接清理掉端边界外的内存

        4)分代收集(Generational Collection)

        按照对象存活周期划分内存(新生代堆->复制算法(因为死得多)、老生代堆->(因为存活率高空间小))

                

     

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值