垃圾收集器与内存分配策略

  一、判断对象是否已死

  1、垃圾收集器在对堆进行回收前,要先判断对象是否已死。而判断的算法有引用计数算法和可达性分析算法;

  2、引用计数算法是给对象添加引用计数器,有地方引用就加1,当引用失效就减1,任何时刻计数器为0的对象就是不可能再被引用的。但是它很难解决对象之间相互循环引用。所以在主流的Java虚拟机里没有用引用计数算法来管理内存。

  3、可达性分析算法是通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。在Java语言中,可作为GC Roots的对象包括下面几种:虚拟机栈(栈帧中的本地变量表)中引用的对象;方法区中类静态属性引用的对象;方法区中常量引用的对象;本地方法栈中JNI(即一般说的Native方法)引用的对象。

  4、引用在JDK1.2之后分为强引用,软引用,弱引用,需引用。

  5、即使在可达性分析后不可达的对象也至少要经历两次标记过程,第一次是可达性分析后没有与GC Roots相关联的引用链,就会被标记进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法,当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,那么就被是为“没有必要执行”,如果执行的对象与引用链上的任何一个对象建立了关联即可拯救自己。

  二、垃圾收集算法

  1、标记-清除算法、标记-整理算法、复制算法、分代收集算法;

  2、分代收集算法是根据对象存活周期的不同来划分为老年代和新生代(默认是15个周期);在新生代中因为有大量对象会死去所以采用的复制算法,在新生代区域中分为一个Eden和两个Survivor区域,新建对象分配到Eden和其中一个Survivor中,每次清理后将活着的对象复制到Survivor区域;HotSpot虚拟机的默认比例是8:1;而老年代中对象存活率高,一般采用标记-清除或者标记-整理算法来进行GC。

  三、HotShot算法实现

  1、枚举根节点:进行可达性分析,从可作为GC Roots的节点查找引用链,可达性分析时会产生GC停顿。并且使用OopMap的数据结构来使得虚拟机可以直接得知哪里存放着对象的引用。HotShot在安全点会停下进行GC。而为了让所有线程在安全点停顿,有两种方案,抢先式中断和主动式中断。还有安全区域概念。

  四、垃圾收集器

  1、Serial收集器时最基本、发展历史最悠久的收集器,单线程收集器。

  2、ParNew收集器其实就是Serial收集器的多线程版本

  3、Parallel Scavenge收集器是一个新生代收集器,它也是使用复制方法的收集器又是并行的多线程收集器。它不同于CMS等收集器的关注点是减少停顿时间,他的目标是达到一个可控制的吞吐量。

  4、Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。

  5、Parallel Old是Parallel Scavenge的老年代版本,使用多线程和“标记-整理”算法。

  6、CMS收集器是一种以获取最短回收停顿时间为目标的收集器,使用“标记-清除”算法。

  7、G1收集器是当今收集器技术发展的最前沿成果之一,G1具有以下特点:并行与并发;分代收集;空间整合;可预测的停顿。

  五、内存分配与回收策略

  1、在Serial/Serial Old收集器下,大多数情况下,对象在新生代Eden区中分配,当Eden区没有足够内存是,发起一次Minor GC。

  2、大对象直接进入老年代。通过-XX:pretenureSizeThreshold参数来设置对象大小的界限,这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制

  3、长期存活的对象将进入老年代 默认经历过15次Minor GC后进入老年代

  4、动态对象年龄判定如果在Survivor空间中相同的年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄

  5、空间分配担保:发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,不安全的话会再计算之前每一次回收晋升到老年代对象容量的平均大小之作为经验值,与老年代的剩余空间进行比较,决定是否进行Full GC来让老年代腾出更多空间。

深入理解Java虚拟机--阅读笔记二的更多相关文章

  1. 深入理解Java虚拟机--阅读笔记一

    Java内存区域 一.java运行时数据区域 1. 程序计数器:程序计数器占据的内存空间较小,是当前运行线程执行的字节码的计数:分支.循环.跳转.异常处理.线程恢复等都要依赖技术器来对执行的字节码进行 ...

  2. 深入理解JAVA虚拟机阅读笔记4——虚拟机类加载机制

    虚拟机把描述类的Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 在Java语言中,类型的加载.连接和初始化过程都是 ...

  3. 深入理解JAVA虚拟机阅读笔记1——JAVA内存区域

    一.Java内存区域 1.程序计数器 线程私有. 当前线程所执行的字节码的行号指示器.由于JAVA是多线程的,因此每个线程都独立的程序计数器. 异常:没有规定任何OutOfMemeryError情况的 ...

  4. 深入理解Java 虚拟机阅读笔记(一)

    1.程序计数器- 占用空间:较小 作用:字节码行号指示器 作用详情:指示指令执行,如(字节码的执行,分支,循环,跳转,异常处理,线程恢复) 特点:线程私有(每个计数器独立计算,上下文相互独立). 2. ...

  5. 深入理解java虚拟机阅读笔记(1)运行时数据区域

    java虚拟机所管理的内存区域主要分为方法区.堆:虚拟机栈.本地方法栈.程序计数器,如图: 1.程序计数器是当前线程所执行的字节码行号指示器,用以记录当前指令执行的位置.程序计数器是线程私有的,每个线 ...

  6. 深入理解Java虚拟机阅读心得(二)

    垃圾收集 程序计数器.虚拟机栈.本地方法栈三个区域随线程而生,随线程而灭:这几个区域的内存分配和回收都具备稳定性,不需要过多的考虑回收的问题.而Java堆和方法区则不一样. Java堆中存储了几乎所有 ...

  7. 深入理解JAVA虚拟机阅读笔记6——线程安全与锁优化

    线程安全:如果一个对象可以安全的被多个线程同时使用,那它就是线程安全的. 一.Java中的线程安全 1.不可变 不可变的对象一定是线程安全的.String.枚举类型.java.lang.Number的 ...

  8. 深入理解JAVA虚拟机阅读笔记3——垃圾回收器

    一.垃圾收集器总览 新生代:Serial. ParNew. Parallel Scavenge 老年代:CMS.Serial Old. Parallel Old 最新的:G1 并行和并发的区别: 并行 ...

  9. 深入理解JAVA虚拟机阅读笔记2——垃圾回收

    线程私有的程序计数器.虚拟机栈和本地方法栈随线程而生,随线程而灭.栈中的栈帧随方法的进入和退出有条不紊的入栈和出栈. 而Java堆和方法区因为需要多大内存.创建多少对象都是不确定的,因此这两个区域是垃 ...

随机推荐

  1. python 数据类型二 (列表和元组)

    一.列表 1.1 列表的介绍 列表是python的基本数据类型之一,其他编程语言也有类似的数据类型,比如JS中的数组,java中的数组等等,它是以[]括起来,每个元素用逗号隔开,而且可以存放各种数据类 ...

  2. 为什么transform对行内元素不生效

    注:赶时间的同学可直接下拉到底,看结论. 我使用transform对一个元素进行位移,代码如下: <div class="box"> <span>今天你吃了 ...

  3. JSX 和 template 随想

    就目前而言,我用到的前端页面开发框架主要有两种:以JSX为主的react和以template为主的vue. 虽然这两种方式各有千秋,但我其实更偏爱template多一些.为什么? 相较于灵活的JSX, ...

  4. SQLAlchemy 快速入门、基础知识

    SQLAlchemy 是Python 编程语言下的一款开源软件.提供了SQL工具包及对象关系映射(ORM)工具. ORM, 全称Object Relational Mapping, 中文叫做对象关系映 ...

  5. web 基础

    web服务器和应用服务器以及web应用框架: web服务器:负责处理http请求,响应静态文件,常见的有Apache,Nginx以及微软的IIS. 应用服务器:负责处理逻辑的服务器.比如php.pyt ...

  6. oracle ASM安装过程中UDEV实现磁盘绑定

    UDEV相较于ORACLE 自己的ASMlib 相对比较成熟. 文章转载自:  Maclean Liu的个人技术博客 [http://www.oracledatabase12g.com/] 在< ...

  7. Storm官方提供的trident单词计数的例子

    上代码: public class TridentWordCount { public static class Split extends BaseFunction { @Override publ ...

  8. Vue笔记:在项目中使用 SCSS

    背景概述 1. CSS预处理器 css预处理器定义了一种新的编程语言,编译后成正常的CSS文件.为CSS增加一些编程的特性,无需考虑浏览器的兼容问题,让CSS更加简洁,适应性更强,可读性更佳,更易于代 ...

  9. git 删除远程分支文件夹

    把不需要版本控制的文件提交到远程分支上后,需要删除远程分支上的文件,用以下操作即可: git rm -r –cached dirname //删除远程文件夹,但保留本地文件夹 git commit - ...

  10. java CAS算法

    CAS算法是硬件对于并发操作的支持,其中包含了三个操作数:内存值,预估值和更新值.没当要执行更新操作时,会先在同步方法中比较内存值和预估值是否相等,如果相等才会用更新值替换内存值,否则什么也不做. p ...