用过 C 语言的开发人员都知道,记忆体的管理一直都是个头疼事, 得自己管理物件的生命周期,不当的记忆体释放或者是使用可能会引起程序的异常,而 java 有 GC 这一个概念,能够自动帮你释放记忆体,我们来看一下它是如何管理记忆体的

  GC 的意思就是 Garbage Collections, 意思就是垃圾回收的意思,java 会判断一个物件是否到了他的生命尽头 (不用了) 来对他进行一个垃圾回收。

  首先要回收垃圾肯定得先判断哪个是垃圾物件,有两种方法

  1. 引用计数法,这种方法每个物件在生成的时候都有一个计数,只要有物件引用他,该数就加一,有物件和他断了联络就减一,知道该物件的计数到 0,这个时候就被当成垃圾物件,被回收掉,但是该方法有缺点,就是不能解决回圈引用的问题,例如 a 引用 b,b 引用 c , c 引用 a,此时三个物件的计数均不等于 0,垃圾回收器就不能回收掉他们

  2. 可达法也叫跟搜索法, 引用了一个根的概念,任何物件的引用能到达跟的都不算是垃圾物件。当然, 也不能一下把它锤死, 但是如果是两次都是他的话, 达不了根的都是垃圾物件

  其次就是垃圾回收的演算法,共有下面几种

  1. 标记清除法 , 首先把垃圾物件标记, 标记完垃圾物件后, 就清除

  其原理就是在一块记忆体区域中标记多个垃圾独物件, 当然对个垃圾物件的位置也可能是不同的, 这就会出现一个缺点, 会出现记忆体碎片, 当要分配一个连续的空间时就不能使用该记忆体区域了, 而且标记过程和清除过程的效率都不算太高, 所以说这只是一个最基础的演算法.

  2. 标记压缩演算法, 此演算法可以说是解决了标记清除演算法所遗留的问题, 也就会记忆体碎片, 该演算法会先标记垃圾物件, 然后把垃圾物件放到记忆体区域的一边, 不是垃圾物件的放到记忆体区域的另一边, 然后清除垃圾物件, 该演算法的优点就是不会出现记忆体碎片, 但是会改变原始的位置.

  3. 复制演算法, 该演算法是把记忆体区域分为两块大小相同的区域, 当一块区域的记忆体满了的时候, 会把存活物件复制到另一个快记忆体区域里面, 然后清除原来的记忆体块儿, 把当前使用的做为正在使用的, 这样也没有记忆体碎片的问题, 但缺点就是要把记忆体分为两块儿, 在存活物件比较多的时候, 要进行多次的复制, 这样也会使效率变低

  JAVA 中的分代收集演算法

  因为各种物件的生命周期不一致, 所以我们把他们分为新生代和老年代

  新生代都是一些生命周期比较短的物件, 我们就是用复制演算法, 老年代都是一些生命周期比较长的物件我们就使用标记清除 和 标记压缩 来清除垃圾物件。