深入理解Java虚拟机阅读心得(二)
垃圾收集
程序计数器、虚拟机栈、本地方法栈三个区域随线程而生,随线程而灭;这几个区域的内存分配和回收都具备稳定性,不需要过多的考虑回收的问题。而Java堆和方法区则不一样。
Java堆中存储了几乎所有的对象实例,垃圾收集器进行对堆的回收之前,需要判断这些对象是否还存活
一。判断对象是否存活
判断对象是否还活着,主要有两种方法
1.引用计数法
给对象添加一个引用计数器,每当一个地方引用时,计数器值加1;
每当一个引用失效时,计数器减1;
任何计数器为0的对象为不可能被使用的对象。
优点:实现简单,判定效率高
缺点:很难解决对象之间的相互循环引用的问题
2.可达性分析法
主流的实现中,都是通过可达性分析法来判定对象是否存活。
该算法基本思想:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链;
当一个对象到GC Roots没有任何引用链相连时(即GC Roots无法到达该对象),称为不可达对象,该对象不可用
此时,可以判定该对象是可回收的对象。
Java中可以作为GC Roots的对象包括以下四种:
(1)虚拟机栈中引用的对象
(2)方法区中类静态属性引用的对象
(3)方法区中常量引用的对象
(4)本地方法栈中JNI(一般说的是Native方法)引用的对象
3.方法区的回收
由于方法区中主要存放的是永久代对象,因此,方法区中进行垃圾收集的性价比一般较低。
永久代的垃圾回收主要分为两类:1.废弃常量 2.无用的类
类的卸载条件比较苛刻,需要同时满足以下三个条件:
(1)该类的所有实例已经被回收,即Java堆中不存在该类的任何实例
(2)加载该类的ClassLoader(即类加载器)已被回收
(3)该类对应的java.lang.Class对象没有在任何地方呗引用,无法在任何地方通过反射访问该类的方法
在大量使用动态代理、反射的场景,需要虚拟机具备卸载类的功能,以保证永久代不会造成内存溢出
4.finalize()
类似 C++ 的析构函数,用于关闭外部资源。
但 try-finally 等方式可以做得更好,并且该方法运行代价很高,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。
当一个对象可被回收时,且被判定为有必要执行该对象的 finalize() 方法,那么可能让该对象自救(只需要重新与引用链上的任何一个对象建立关系即可)。
自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会再调用该方法。
二。强引用与软引用
Java对引用的概念分为四种,从强到弱依次为:强引用,软引用,弱引用,虚引用
1.强引用
代码中普遍存在的类似 Object obj = new Object()这种,只要强引用在,该对象永远不会被回收
2.软引用
用来描述一些还有用但非必须的对象;提供了SoftReference类来实现软引用
在系统发生内存溢出异常之前,会把这些对象列入回收范围之中,进行第二次回收
3.弱引用
也是用来描述非必须对象,但是比软引用更弱;提供了WeakReference类来实现
弱引用关联的对象,只能生存到下一次垃圾收集发生之前。
当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
4.虚引用
最弱的引用关系;提供PhantomReference类实现
一个对象是否有虚引用的存在完全不会对其生存时间产生影响,同时也无法通过虚引用来取得一个对象的实例。
设置虚引用的唯一目的是,通过虚引用在这个对象被回收时收到一个系统通知
深入理解Java虚拟机阅读心得(二)的更多相关文章
- 深入理解Java虚拟机阅读心得(一)
JVM(Java Virtual Machine) 即Java虚拟机,是一种用于计算设备的规范,用于运行Java程序编译后得到的字节码文件(Class文件) 一.JVM的内存区域 1.程序计数器(Pr ...
- 深入理解Java虚拟机--阅读笔记二
垃圾收集器与内存分配策略 一.判断对象是否已死 1.垃圾收集器在对堆进行回收前,要先判断对象是否已死.而判断的算法有引用计数算法和可达性分析算法: 2.引用计数算法是给对象添加引用计数器,有地方引用就 ...
- 深入理解Java虚拟机阅读心得(三)
Java中提倡的自动内存管理最终可以归结为自动化的解决两个问题: 给对象分配内存 回收分配给对象的内存 先说说回收这一方面的两个主要知识点 一.垃圾收集算法 1.标记-清理算法 首先标记出所有需要回收 ...
- 《深入理解Java虚拟机》(二)Java虚拟机运行时数据区
Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第二章 ,为了整理思路,简单记录一下,方便后期查阅. 2.2 运行时数据区域 Java虚拟机 ...
- 深入理解java虚拟机---Class文件(二十)
无符号数.表 当实现了不同语言的编译器,比如jython,jruby等等,那么就可以利用这些语言编写代码,通过各自的编译器编译成符合jvm规范的字节码文件,就可以利用jvm来执行了. Class文件在 ...
- 深入理解Java虚拟机--阅读笔记一
Java内存区域 一.java运行时数据区域 1. 程序计数器:程序计数器占据的内存空间较小,是当前运行线程执行的字节码的计数:分支.循环.跳转.异常处理.线程恢复等都要依赖技术器来对执行的字节码进行 ...
- 深入理解JAVA虚拟机阅读笔记4——虚拟机类加载机制
虚拟机把描述类的Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 在Java语言中,类型的加载.连接和初始化过程都是 ...
- 深入理解JAVA虚拟机阅读笔记1——JAVA内存区域
一.Java内存区域 1.程序计数器 线程私有. 当前线程所执行的字节码的行号指示器.由于JAVA是多线程的,因此每个线程都独立的程序计数器. 异常:没有规定任何OutOfMemeryError情况的 ...
- 深入理解Java 虚拟机阅读笔记(一)
1.程序计数器- 占用空间:较小 作用:字节码行号指示器 作用详情:指示指令执行,如(字节码的执行,分支,循环,跳转,异常处理,线程恢复) 特点:线程私有(每个计数器独立计算,上下文相互独立). 2. ...
随机推荐
- 彻底理解cookie,session,token
发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议, 就是请求加响应, 尤其是我不用 ...
- 团体程序设计天梯赛(CCCC) L3021 神坛 的一些错误做法(目前网上的方法没一个是对的) 和 一些想法
团体程序设计天梯赛代码.体现代码技巧,比赛技巧. https://github.com/congmingyige/cccc_code
- Java基础 -- final关键字
在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们来了解一下final ...
- [SDOI2006] 保安站岗
题目链接 第一遍不知道为什么就爆零了…… 第二遍改了一下策略,思路没变,结果不知道为什么就 A 了??? 树形 DP 经典问题:选择最少点以覆盖树上所有点(边). 对于本题,设 dp[i][0/1][ ...
- L1-023 输出GPLT (20 分)
L1-023 输出GPLT (20 分) 给定一个长度不超过10000的.仅由英文字母构成的字符串.请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符.当然,四种字符(不区 ...
- 防止Web表单重复提交的方法总结
在Web开发中,对于处理表单重复提交是经常要面对的事情.那么,存在哪些场景会导致表单重复提交呢?表单重复提交会带来什么问题?有哪些方法可以避免表单重复提交? 表单重复提交的场景 1.场景一:服务端未能 ...
- Geometric regularity criterion for NSE: the cross product of velocity and vorticity 2: $u\times \om\cdot \n\times \om$
在 [Lee, Jihoon. Notes on the geometric regularity criterion of 3D Navier-Stokes system. J. Math. Phy ...
- 函数语法:JS获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度(转载)
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...
- 转:spring boot log4j2配置(使用log4j2.yml文件)---YAML 语言教程
转:spring boot log4j2配置(使用log4j2.yml文件) - CSDN博客http://blog.csdn.net/ClementAD/article/details/514988 ...
- 激活函数——sigmoid函数(理解)
0 - 定义 $Sigmoid$函数是一个在生物学中常见的S型函数,也称为$S$型生长曲线.在信息科学中,由于其单增以及反函数单增等性质,$Sigmoid$函数常被用作神经网络的阈值函数,将变量映射到 ...