jvm读书笔记之对象是否存活

来源:互联网 发布:php 替换字符串 编辑:程序博客网 时间:2024/05/18 15:51

1.私有区域

jvm的内存区域可以从线程的角度看,分为共享的内存区域和私有的内存区域。对于私有的内存区域,如程序计数器、虚拟机栈里面的局部变量表等、本地方法栈等,从每个线程的出生就创建,到线程销毁就结束。方法的进入执行到退出就是栈中的进栈和出栈就是调整栈指针的位置而已。

2.共享区域

jvm的共享区域是堆和方法区。我们在堆中存放对象。在方法区中存储类被加载的信息、静态变量、以及定义的常量等。而这共享的区域才是应该特殊区分对待。

  2.1 引用计数算法

引用计数算法是判断对象是否存活的算法。

其没有使用根集的垃圾回收算法。就是通过计数来判断对象是否存活。

思想:

实际上就是为每个对象分配一个计数,如果刚创建的对象分配的计数为0,如果该对象被引用就让该计数加1那么该计数为1。如果

该对象出了作用域,失去了被引用,那么计数减一为0了。垃圾回收器来回收对象时,如果对象计数为0,那么说明没有被引用就会被回收。

  2.2可达性分析算法

可达性分析算法是判断对象是否存活的另外一种算法。

思想:

就是将当前创建对象作为垃圾回收的根节点,然后每次从该根节点遍历出一堆节点,再将这些节点作为根节点再遍历。一直遍历直到终止。就形成了很多条引用链。就是类似于数据结构的图。是一种多条链组成的网状结构。从根节点到网中的任一节点都没有引用,那么就说明此对象没有任何引用就可以被回收了。(想想遍历的方式应该是借助辅助队列实现的广度优先搜索,还没看源码)

java中的GC根节点的对象:

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

方法区中类静态属性引用的对象。

方法区中常量引用的对象。

本地方法栈中JNI引用的对象(Native修饰的方法)。

  2.3 对象的引用

到底java中的引用是咋回事?

在C语言中我们常常使用指针来传参,而C语言中的指针往往都是指向一个变量的地址,通过地址去获取存放在该地址对应物理内存中的变量。但是在java中的引用,引用变量是直接指向对象(java直接将指针进行了封装,避免我们像C语言中先取地址,在取完地址后还得再通过地址获取变量。这么麻烦)

java中的引用有哪些?

(1).强引用:就是在程序中普遍存在的。如Object obj =new Object();强引用存在,那么垃圾回收器就不会回收掉该引用的对象

(2).软引用:就是一些有用但非必须的对象。如果系统将要发生内存溢出,那么垃圾回收器会对软引用对象回收。如果回收之后,还是内存不够,就报内存溢出异常。使用SoftReference来实现软引用。

(3).弱引用:就是程序中非必需的对象,只能在垃圾回收器回收之前存活。不管内存是否充足,都要被进行回收掉弱引用对象。使用WeakReference类来实现弱引用。

(4).虚引用:是最弱的一种引用关系,虚引用对于对象来说存在与否对于对象的生存没有影响。至于虚引用存在的目的就是为了能在对象被垃圾回收器回收时收到系统通知。使用PhantomReference类实现虚引用。

3.方法区的回收

方法区又叫永久代,java虚拟机可以回收方法区也可以不回收方法区。方法区主要回收的垃圾是没用的常量和没用的类。

如何判断该常量和类无用?

该类的实例都已经被回收,那么java堆中不存在该类的实例了。

加载该类的ClassLoader已经被回收。

该类对应的对象没有被引用,即使通过反射的方式。



------------------------坚持每天进步一点点


0 0
原创粉丝点击