首页 > 代码库 > 二、Java如何分配和回收内存?Java垃圾收集器如何工作?

二、Java如何分配和回收内存?Java垃圾收集器如何工作?

线程私有的内存区域随用户线程的结束而回收,内存分配编译期已确定,内存分配和回收具有确定性。共享线程随虚拟机的启动、结束而建立和销毁,在运行期进行动态分配。垃圾收集器主要对共享内存区域(堆和方法区)进行垃圾收集回收。

Java如何实现内存动态分配和内存垃圾的回收?

1、哪些内存需要回收(垃圾收集器内存回收的对象)?已经“死亡”的对象,那如何判定对象已经“死亡”了?

     Java堆回收的内存:已经”死亡“的对象

     方法区回收的内存:废弃的常量和无用的类

2、什么时候进行回收?什么情况下垃圾收集器自动回收内存?

3、如何回收?Java虚拟机是如何实现内存回收的?

(一)Java堆内如何判断对象已经“死亡”

1、引用计数算法:

   算法思路:通过对象的引用计数器判断,引用的时候递增计数器,引用失效后递减计数器。

   缺点:难以解决循环引用问题

2、可达性分析算法:

  算法思路:判断对象到GC Root节点是否存在引用链,如果不存在则说明对象不可用。

  缺点:(1)当GC Root点多的时候逐个检查消耗时间过多

           (2)进行分析的时候GC需要停顿,停顿所有Java执行线程。

   GC Root节点:主要存在全局性引用(常量,静态属性)、执行上下文(如栈帧的本地变量表)中,

   具体可作为GC Root节点的有:

                            1)虚拟机栈(栈帧内的本地变量表)中引用的对象

                            2)方法区内的静态属性和常量引用的对象

                            3)本地方法栈中本地方法引用的对象

            

3、对象引用的划分

引用类型

特点和用途

内存回收时机

实现

强引用

操作引用对象。 不可回收 类似 Object boj=new Object();的引用

软引用

用来描述有用但非必需的对象,比强引用弱 第二次回收 SoftReference

弱引用

用来描述有用但非必需的对象,比软引用弱 下一次垃圾回收的时候,无论内存是否足够都进行回收。 WeakReference

虚拟用

实现对象在垃圾收集器回收的时候收到系统通知。最弱的引用关系 下一次垃圾回收的时候 PhantomReference

(二)方法区内如何判断废弃的常量和无用的类?

1、如何判定废弃的常量

和堆内存对象的存活判断类似

2、如何判定无用的类

成为无用类的条件:

  (1)所有实例对象都已经回收

  (2)加载该类的ClassLoader已经回收

  (3)类的Class信息不存在引用和反射访问

(三)垃圾收集器如何回收内存?

1、标记-清除算法

2、复制算法

3、标记-整理算法

4、分代收集算法

(1)算法实现:

(2)堆内存划分:

 

新生代

老年代

存活率 存活率低 存活率高
回收算法 复制算法(Eden,From Survivor,To Survivor) 标记-清理算法;标记-整理算法
有无额外空间担保

 

 

 

(四)如何分配内存?(内存的分配策略)

  1、对象优先在Eden分配

2、大对象(需要大量连续内存空间的对象)直接进入老年代

3、长期存活的对象直接进入老年代

二、Java如何分配和回收内存?Java垃圾收集器如何工作?