JVM内存区域和垃圾收集器
基于《深入理解java虚拟机》
Java内存区域
运行时数据区
程序计数器
占有一块较小的内存空间,线程隔离,每个线程都有私有的一个独立的程序计数器。是当前线程锁执行的字节码的行号指示器,通过这个计数器来选取下一条用来执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础的操作都要依赖程序计数器。
虚拟机栈
每个方法被执行的时候,都会创建一个栈桢,存储了局部变量表、操作数栈、动态连接、方法出口等的信息。一个方法从调用到执行完毕的过程,就是该方法的栈桢从虚拟机栈中入栈到出站的过程。
局部变量表存放了编译期已知的各种基本数据类型和引用数据类型,在局部变量表中以局部变量槽(Slot)来表示,64位的long和double类型会占用2个slot。
本地方法栈
调用本地(Native)方法服务,非Java实现的方法。
堆
垃圾收集器管理的内存区域。几乎所有的对象创建都在该区域分配内存。
元空间
jdk8之后叫元空间,存储类信息和即时编译后的代码。常量池、类型信息、静态变量等存放在堆中。
直接内存
垃圾收集算法
引用计数算法
在对象中添加一个引用计数器,有一个地方引用该对象,数值就加一,引用失效数值就减一。但是该算法无法解决循环引用的问题。
可达性分析算法(标记算法)
通过根对象“GC Roots”来作为起始节点集,根据引用关系乡下搜索,走过的路径成为“引用链”。当GC Roots无法到达该对象,证明该对象没有引用是不再被使用,可回收的。
GC Roots对象:
- 虚拟机栈引用的对象(栈桢中的本地变量表)
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- JNI方法引用的对象,native方法
- JVM内部引用,基本数据类型的Class对象,常驻的异常对象,系统类加载器
- 被synchronized持有的对象
- JVM内部情况的一些JMXBean、JVMTI、本地代码缓存等
分代收集理论
- 弱分代(大部分对象是朝生夕灭的)
- 强分代(熬过多次垃圾收集的对象越难以被回收)
- 跨代引用(新生代跟老年代存在引用,在minor GC的时候不应该扫描整个老年代,而只需要在新生代建立一个记忆集(Remembered Set)将老年代切分成若干个小块,标识出哪一块老年代区域跟新生代存在引用关系,在minor GC的时候只需要将该部分的老年代加入到GC Root里面进行扫描,而不用全局扫描整个老年代)
标记 - 清除算法
是最基础的收集算法。
回收前
回收后
如图所示,在清理垃圾对象后,堆内的空闲空间是碎片化的、不连续的。当需要存放大对象的时候,在堆内申请一块连续的内存空间,就不得不提前触发新的一次的垃圾回收动作。
如果堆内含有大量的对象,就要进行大量的标记和清除的动作,随着堆内存的增大,对象数量的增加,效率会变得越来越低。
标记 - 复制
回收前
回收后
该算法解决标记清除算法面对大量对象时回收效率低的问题,同时也解决了存放大对象因为无法申请连续内存空间而不得不执行另一次垃圾回收的问题。在存放大对象的时候,只需要移动堆顶指针按所需内存空间进行分配,但是该算法的空间浪费十分严重,解决垃圾清除算法问题的代价是浪费了一半的内存空间。
标记 - 整理
回收前
回收后
在标记-清除算法上,还添加了一个移动存活对象的操作,没有标记-复制算法浪费50%的空间。相较前两种算法,该算法是一种移动式算法,而前两种算法是非移动式的算法。但是移动操作需要停止所有用户应用程序才能进行,这个停顿被称为STW——Stop The World。
经典垃圾回收器
新生代
Serial
ParNew
Parallel Scavenge
老年代
Serial Old
Parallel Old
CMS
Garbage First
Serial和Serial Old收集器
Serial收集器是最基本、发展历史最悠久的收集器,曾是(JDK1.3.1之前)虚拟机新生代收集的唯一选择。
Serial收集器是一个单线程的收集器。“单线程”的意义不仅仅是它只会使用一个CPU或一条收集器线程去完成垃圾收集工作,更重要的是它在垃圾收集的时候,必须暂停其他所有工作的线程,直到它收集结束。
Serial收集器是HotSpot虚拟机运行在Client模式下的默认新生代收集器。
Serial收集器具有简单而高效,由于没有线程交互的开销,可以获得最高的单线程收集效率(在单个CPU环境中)。
“-XX:+UseSerialGC”:添加该参数来显式的使用Serial垃圾收集器。
ParNew和Serial Old收集器
ParNew收集器是Serial收集器的多线程并行版本。
ParNew收集器是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The Word、对象分配规则、回收策略等都与Serial收集器一样。
ParNew收集器是许多运行在Server模式下的虚拟机首选的新生代收集器,其中一个原因是,除了Serial收集器之外,目前只有ParNew收集器能与CMS收集器配合工作。
“-XX:+UseConcMarkSweepGC”:指定使用CMS后,会默认使用ParNew作为新生代收集器。
“-XX:+UseParNewGC”:强制指定使用ParNew。
“-XX:ParallelGCThreads”:指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相同。
Serial Old收集器
Serial Old收集器是Serial的老年代版本,使用标记-整理算法。服务端使用的情况下,在JDK5及之前版本跟Parallel Scavenge收集器搭配使用,还有就是作为CMS收集器失败时候的备用。
Parallel Scavenge和Parallel Old收集器(JDK8默认)
Parallel Scavenge,新生代收集器,基于标记-复制的算法,跟ParNew很相似,但是PS收集器关注的点是达到一个可控制的吞吐量,其他收集器关注的点在于尽可能的缩短STW的时间。
“-XX:MaxGCPauseMillis” 参数允许的值是一个大于0的毫秒数,收集器将尽可能的保证内存垃圾回收花费的时间不超过设定的值(但是,并不是越小越好,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的,如果设置的值太小,将会导致频繁GC,这样虽然GC停顿时间下来了,但是吞吐量也下来了)。
“ -XX:GCTimeRatio”参数的值是一个大于0且小于100的整数,也就是垃圾收集时间占总时间的比率,默认值是99,就是允许最大1%(即1/(1+99))的垃圾收集时间。
“-XX:UseAdaptiveSizePolicy”参数是一个开发,如果这个参数打开之后,虚拟机会根据当前系统运行情况收集监控信息,动态调整新生代的比例、老年大大小等细节参数,以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略。
Parallel Old是Parallel Scavenge的老年代版本,基于标记-整理算法,支持多线程并行收集。
在JDK1.6才出现。
CMS收集器
Concurrent Mark Sweep。是一种以获取最短回收停顿时间为目标的老年代收集器。
CMS是基于标记-清除算法的收集器,但是他的运作过程相较之前几种要更复杂一点,分为4个阶段:
初始标记
需要STW
用于标记GC Roots能直接关联到的对象。
并发标记
从GC Roots开始遍历整个对象图,耗时长但是不需要STW。
重新标记
三色标记算法。修正并发标记期间因为用户程序继续运行导致标记产生变动的对象,比初始标记的STW时间长一点,但是比并发标记的时间短。
并发清除
清楚标记已经死亡的对象,基于标记-清除算法,不需要移动对象,可以跟用户线程并发执行。
优点:并发收集、低停顿。
缺点:
CMS收集器对CPU资源非常敏感。虽然在两个并发阶段不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量下降。CMS默认启动的回收线程数是(CPU数量+3)/4。
CMS收集器无法处理浮动垃圾,可能出现“Conturrent Mode Failure”失败而导致另一次Full GC产生。由于CMS并发清除阶段用户线程还在运行,伴随着程序还在产生新的垃圾,这一部分垃圾出现在标记之后,CMS无法在当次收集中处理掉它们,只能留到下次再清理,这一部分垃圾称为“浮动垃圾”。也正是由于在垃圾收集阶段用户线程还在运行,那么也就需要预留有足够的内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等待老年代填满之后再进行收集,需要预留一部分空间给并发收集时用户程序使用。可以通过“-XX:CMSInitiatingOccupancyFraction”参数设置老年代内存使用达到多少时启动收集。
由于CMS收集器是一个基于“标记-清除”算法的收集器,那么意味着收集结束会产生大量碎片,有时候往往还有很多内存未使用,可是没有一块连续的空间来分配一个对象,导致不得不提前触发一次Full GC。CMS收集器提供了一个“-XX:UseCMSCompactAtFullCollection”参数(默认是开启的)用于在CMS收集器顶不住要FullGC时开启内存碎片整理(内存碎片整理意味着无法并发执行不得不停顿用户线程)。参数“-XX:CMSFullGCsBeforeCompaction”来设置执行多少次不压缩的Full GC后,跟着来一次带压缩的(默认值是0,意味着每次进入Full GC时都进行碎片整理)。
G1收集器
没有固定的新生代,老年代的概念。基于Region的内存布局形式,是一个里程碑式的收集器。
步骤:
- 初始标记
标记GC Roots的直接关联对象,STW但是耗时很短,而且是借用minor GC的时候同步完成的。 - 并发标记
扫描堆内对象图,耗时长但是可以跟用户线程并发执行。完成扫描后处理SATB记录下的在并发时有变动的对象。 - 最终标记
短暂的STW,处理并发标记结束后最后少量的SATB记录。 - 筛选回收
更新Region的统计数据,对Region的回收价值和成本进行排序,根据用户期望的停顿时间制定回收计划。必须STW,将回收的部分Region里的存活对象移动到空的Region中,再清理掉旧Region的全部空间。
总结
三色标记算法
增量更新
SATB原始快照
JVM内存区域和垃圾收集器相关推荐
- JVM内存模型及垃圾收集策略解析(一)
http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/jvm_model.html JVM内存模型是Java的核心技术之一,之前51CTO曾为大家介绍 ...
- JVM内存管理------垃圾搜集器参数精解
转载自 JVM内存管理------垃圾搜集器参数精解 垃圾搜集器选择参数 UseSerialGC:开启此参数使用serial & serial old搜集器(client模式默认值). U ...
- 走进JVM【二】理解JVM内存区域
引言 对于C++程序员,内存分配与回收的处理一直是令人头疼的问题.Java由于自身的自动内存管理机制,使得管理内存变得非常轻松,不容易出现内存泄漏,溢出的问题. 不容易不代表不会出现问题,一旦内存泄漏 ...
- Java虚拟机------JVM内存区域
JVM内存区域运行时数据区域分为两种: JVM内存区域 运行时数据区域分为两种: 线程隔离的数据区: 程序计数器 Java虚拟机栈 本地方法栈 所有线程程共享的数据区: Java堆 方法区 JVM 内 ...
- mfc强制局部区域刷新_简述JVM内存区域划分
我们在Java编程时少不了程序优化,而程序优化的前提是知道JVM的内存是如何划分的,那么我们今天来大体了解下. 在看JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 如上图所示,首先Ja ...
- JVM的7种垃圾收集器
原文地址:Java虚拟机垃圾回收(三) 7种垃圾收集器 Java虚拟机垃圾回收(三) 7种垃圾收集器 主要特点 应用场景 设置参数 基本运行原理 在<Java虚拟机垃圾回收(一) 基础>中 ...
- JVM内存区域(Java内存区域)、JVM垃圾回收机制(GC)初探
一.JVM内存区域(Java内存区域) 首先区分一下JVM内存区域(Java内存区域)和Java内存模型(JMM)的概念.Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Ja ...
- 《探索JVM内存区域》
一.为什么要了解JVM内存区域 二.结识JVM中的"内存"成员 1. 程序计数器(PC=Program Counter Register) 2. JVM栈(Java Virtual ...
- 01.JVM内存区域
01.JVM内存区域 0101.运行时数据区 程序计数器 存储:下一段要执行的代码的地址 共享:线程私有 特点:占用非常小的内存空间 OOM:唯一不会出现OOM的区域 虚拟机栈: 存储: 方法执行的线 ...
最新文章
- pandas使用extract函数根据正则表达式从dataframe指定数据列的字符串中抽取出数字(设置expand=false之后返回的为series)、将series转化为dataframe
- 人脸标注工具源码解读
- Graham Scan凸包算法
- 改变程序设计、图灵奖得主、美国第一位计算机科学女博士,程序媛进击史
- java day59【 AOP 的相关概念[理解] 、 Spring 中的 AOP[掌握] 、 Spring 整合 Junit[掌握] 】...
- 微信收到消息很慢无法连接服务器,微信消息总是延迟接收怎么办?
- 高效实现斐波那契数列(Fibonacci数列)
- 什么网页游戏是按地地狱划分服务器的,不思议迷宫地域边境详细攻略 全方位介绍地狱边境所有玩法...
- 入门计算机的粗略学习-Day13
- DirectSound学习(二)--流式缓冲区
- Java开发中各类名词解释大全
- 网易或入股MSN中国 门户再现竞争新局
- 在word中写出打勾的方框
- 设计模式复合使用_结构设计模式:复合模式
- yun mysql 安装_yun安装mysql
- Markdown做笔记或写博客
- android 4.0板卡接收视频源,在Digilent Nexys Video板卡上实现HDMI I/O视频处理系统的软件配置介绍...
- MWPhotoBrowser性能优化
- Android设置壁纸的几种方案
- 物联卡管理平台是否重要