java垃圾回收机制。理解这一篇足以闯世界

一、垃圾回收机制的前世今生

    说起垃圾回收机制(GC),很多人会以为是java语言的伴生产物,其实早在java之前GC就已经出现了,早在1960年Lisp这门语言就使用了内存动态分配交和垃圾回收技术。

二、他是依据什么回收的   

    在这之前先简单说说java运行时候的内存区:

(1)线程私有区

程序计数器:记录正在执行的虚拟机的字节码的地址;

虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧;

本地方法栈:虚拟机的Native方法执行的内存区;

(2)线程共享区

java堆:对象分配内存的区域,这就是垃圾回收的主战场;

方法区:存放类信息、常量、静态变量等数据的地方,垃圾回收的副战场;

其中jvm线程的私有区是随着方法的执行的创建而产生,随着方法执行完成线程释放自然就回收。这部分jvm已经处理好,不需要我们特别关心。而线程共享区是我们主要关注的地方。

2 jvm线程回收的方法

    2.1引用计数法

            引用计数法就是当一个对象创建的时候,就会给该变量分配一个变量(计数器),这个变量(计数器)计数设置成1,当任何地方使用他或者引用他的时候,这个变量就会加1,当这个这个引用这个对象的生命周期结束或者被设置成为一个新值的时候,那么这个对象的计数器就会减1,当计数器为0的时候jvm就会把他回收掉。

        这种方法看似简单,无法解决相互引用的问题,比如当A引用了B,B又引用了A。这时候A和B的计数器都增加了1,这时候A和B都不在被外界使用了,但又相互的引用 计数器 = 1 永远无法被回收


2.2 可达性算法

    可达性算法通俗点将就是,通过一个起点开始往下寻找引用,找到一个就形成一条链。如果一个对象没有任何可以到达GC Roots的链,也就是这个对象不可达,那么恭喜他,奖励jvm回收一套。他的学名叫做 GC Roots Tracing ,在这里设计到两个概念一个叫GC Roots也就是我们刚才说的起点,另一个就是可达性,就是链条是怎么形成的。

2.2.1 哪些可以成为GC Roots

    方法区:类的静态变量或常量

    虚拟机栈:栈帧的局部变量表

    本地方法栈:JINI

回顾刚才,在引用计数器中A和B 虽然被释放了,但是都互相引用不能被回收。从可达性算法上看,A和B互相引用形成链,由于A和B都被释放,GC Roots 也不存在了,A和B的链条被孤立,所以被回收。



既然java有回收机制,那么为什么会存在内存泄漏?下一篇文章带你详解。

你可能感兴趣的:(java垃圾回收机制。理解这一篇足以闯世界)