深入理解java虚拟机-第三章

1、概述

2、对象已死吗?

引用计数器

  给对象添加一个引用计数器,每当有引用时,计数器加1,引用失效时,计数器减1;任何时刻计数器为0的对象就是不可能再被使用的。

  若对象是循环引用,则无法处理。JVM不使用。

可达性分析算法

  通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所经过的路径称为引用链(Reference Chain),当一个对象没有任何引用链相连时,表明该对象不可用。

  Java语言中,可作为 GC Roots的对象包括如下:

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

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

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

    本地方法栈中JNI(即一般说的Native方法)引用的对象。

Java中的引用:

  强引用(Strong Reference) 类似“Object obj=new Object()”,这类的引用,只要强引用还存在,对象永远不会被回收。

  软引用(Soft Reference)用来描述一些还有用但并非必需的对象。在系统将要发生内存溢出前,会对这类对象进行回收;如果这次回收还没有足够的内存,才会抛出内存溢出异常。SoftReference类来实现。

  弱引用(Weak Reference) 非必需的对象,但强度比软引用更弱一点。当垃圾收集器工作时,无论内存是否够用,都会回收这类引用。WeakReference来实现。

  虚引用(Phantom Reference)幽灵引用或幻影引用,最弱的一种引用关系,完全不对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,唯一目的就是能在这个对象被收集器回收时收到一个系统通知,用PhantomReference来实现

3、垃圾收集算法

标记清除算法 Mark-Sweep

  首先标记出所要回收的对象,在标记完成后统一回收所有被标记的对象。可能会造成碎片。

复制算法Copying

  将可用内存按容量划分为大小相等的两块,每次中使用其中的一块,当这一块用完了,将存活的对象复制到另一块中,然后把已使用的一块清空。

     每次对整个半区进行内存回收,也不用考虑内存d碎片;代价为只使用了内存的一半。

  现在商业虚拟机都使用这种算法来回收 新生代,不过将内存分为较大的Eden和两块较小的Survior,每次只使用Eden和一块Survior,回收时一次复制到另一块Survivor,默认比例8:1:1.

标记-整理算法

  与 标记-清除算法一样,但是后续步骤是让所有存活的对象都向一端移动,最后直接清理掉端边界以外的内存。

分代收集算法 Generation Collection

  根据对象存活周期的不同将内存划分为几块

默认的,新生代与老年代的比例值为1:2(可以通过参数-XX:NewRatio来指定

Eden:from:to=8:1:1可以通过--XX:SurvivorRatio来指定

4、HotSpot的算法实现

枚举根结点

  从可达性分析中从GC Root节点找引用链的操作中,需要停顿所有Java执行线程(Stop The World, STW)。HotSpot的实现中使用一组称为OopMap的数据结构来实现,当执行系统停顿下来后,并不需要一个不漏的检查所有执行上下文和全局的引用位置。

安全点

安全区域

5、垃圾收集器

Serial收集器

  单线程的收集器,必需暂停其他所有的工作线程,简单而高效。

ParNew

  Serial的多线程版本,暂停其它工作线程,启用多个回收线程来回收。

Parallel Scavenge收集器

  目标是达到一个可控制的吞吐量,吞吐量就是Cpu运行用户代码的时间和CPU总消耗时间的比值。

Serial Old收集器

  Serial收集器的老年代版本。

Parallel Old收集器

  老年代的Parallel Scavenge收集器,使用多线程和“标记-整理”算法。

CMS收集器 Concurrent Mark Sweep

  以获取最短回收停顿时间为目标的收集器

    初始标记 (CMS initial mark), Stop the World,只是标记一下GC Roots能直接关联到的对象,速度很快

    并发标记(CMS concurrent mark),进行GC Roots Tracing的过程。

    重新标记(CMS remark), Stop the World, 为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录

    并发清除(CMS concurrent sweep)

G1收集器 Garbage-first

  面向服务端应用的垃圾收集器

  1、并发与关行。 充用利用多CPU、多核环境下的硬件优势,来缩短Stop-The-World从停顿的时间,可以通过并发的文萃上java程序继续执行

  2、分代收集。 分不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象

  3、空间整合。从整体来看是基于“标记-整理”算法的收集器,从局部上来看是基于“复制”算法实现的, 运行期间不会产生内存碎片,收集后能提供规整的可用内存。

  4、可预测的停顿

Young Generation: Serial、ParNew、Parallel Scavenge、G1

Tenured(old) Generation:CMS、Serial Old、Parallel Old

6、内存分配和回收策略

  对象优先在Eden分配,当Eden区没有足够空间分分配时,触发一次GC

  大对象直接进入老年代

  长期存活的对象进行老年代

    虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden出生并经过第一次MinorGC后仍然存活,并且能被Survior容纳的话,将被移动到Survivor空间中,并且对象年龄为1.

    对象在Survivor中每一次Minor GC,年龄增加1,当年龄增加到一定程序,就晋升老年代

   动态对象年龄判定

    为了更好地适应不同程序的内存状态,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivorp空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代

  空间分配担保

时间: 2024-11-15 18:01:48

深入理解java虚拟机-第三章的相关文章

深入理解java虚拟机-第六章

第6章 类文件 6.3 Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流. Class文件格式采用一种类似C语言结构伪结构存储数据,这种伪结构中只有两种数据类型:无符号数和表 无符号数属于基本的数据类型以u1,u2,u4,u8来分别代表一个字节.2个字节,4个字节.8个字节的无符号数,无符号数可以用来描述数字.索引引用.数量值或者按照UTF-8编码构成字条串值. 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表习惯性地以 _info 结尾. 表 Clas

深入理解java虚拟机-第七章

第7章 虚拟机类加载机制 类的加载的时机 加载 Loading, 连接 Linking(验证 Verfiication, 准备Preparation, 解析 Resolution) 初始化 Initialization, 使用Using和卸载 Unloading 类加载的过程: 1,加载: 加载是“类加载" class loading过程珠一个阶段,在加载阶段,虚拟机需要完成以下3个事情. 1 通过一个类的全限定名来获取定义此类的二进制字节流 2 将这个字节流所代表的静态存储结构转化为方法区的运

深入理解java虚拟机-第入章

第8章 虚拟机字节码执行引擎 8.2 运行时栈帧结构 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构. 每一个栈帧包括了局部变量表.操作数栈.动态连接.方法返回地址和一些额外的附加信息. 在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧 Current Stack Frame,与这个栈帧相关联的方法称为当前方法. 局部变量表: Local Variable Table是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量. 在Java程序编译为Cl

深入理解java虚拟机-第四章

第4章 虚拟机性能监按与故障处理工具 jps 虚拟机进程状况工具 jstat 虚拟机统计信息监视工具 JVM Statistics Monitoring Tool jstat [ option vmid [interval[s|ms] [count]] jstat -gc 2764 250 20 其中option的选项: -class  -gc  -gccapacity -gcutil ...... jinfo java配置信息工具 jmap Java内在映射工具 用于生成堆转储快照 也可配置

深入理解java虚拟机-第13章-线程安全与锁优化

第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施,通常需要付出很大甚至是不切实际的代价,在java api中标注自己是线程安全的类,大多数都不是绝对的线程安全 3 相对线程安全 4 线程兼容  对象本身不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全使用 5 线程对立 线程安全的实现方法 1 互斥同步 Murua

深入理解java虚拟机-第12章Java内存模型与线程

第12章 Java内存模型与线程 Java内存模型  主内存与工作内存: java内存模型规定了所有的变量都在主内存中,每条线程还有自己的工作内存. 工作内存中保存了该线程使用的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行. 内存间交互操作: 1 lock 作用于主内存的变量,它把一个变量标识为一个线程独占的状态. 2 unlock 作用于主内存的变量,把锁定的变量释放出来 3 read 作用于工作内存的变量,把一个变量的值从主内存传输到线程的工作内存中. 4 load 作用于工作

《深入理解Java虚拟机》读书笔记---第二章 Java内存区域与内存溢出异常

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来.这一章就是给大家介绍Java虚拟机内存的各个区域,讲解这些区域的作用,服务对象以及其中可能产生的问题. 1.运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 1.1程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型中里,字

《深入理解Java虚拟机》读书笔记---第一章 走进Java

一.为什么要读此书 <深入理解Java虚拟机>这本书读了很多次,每次读都会有不一样的感受.首先说一下为什么要读这本书,如果把Java比喻成乾坤大挪移,那了解虚拟机的工作原理就是练习九阳神功,java语言是招式,对虚拟机的认识是内功心法,只有内功心法强大,所使的招式才强大,这就是为什么阳顶天只能把乾坤大挪移练到第四层,而张无忌能练到第七层.由于java虚拟机的强大,把很多功能都隐藏了,例如内容管理,垃圾回收机制等,使得很多java程序猿对这一块的知识所有缺失,编码的时候也是似懂非懂的,以至于遇到

《深入理解Java虚拟机》读书笔记——第1章 走近Java

(注:原文请见<深入理解Java虚拟机>周志明 著,知识点部分参考百度百科) 总述 第1章分为两个部分:Java概述及自己动手编译JDK的教程. 1 Java概述 介绍了Java的整体特性.Java的技术体系组成.Java及JVM的发展史. 1.1 Java的总体特性 1)Java不仅仅是一门编程语言,更是由一系列计算机软件和规范组成的技术体系. 2)Java具有众多优点: a.Java虚拟机在千差万别的物理机上建立了统一的运行平台,实现了跨平台性.(主要) b.提供了相对安全的内存管理和访问