JAVA内存模型及垃圾回收自我总结
本文为原创,根据《深入理解java虚拟机》和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻。
JAVA内存模型:
上图中:局部变量表所需的内存在编译期已经分配完成 表达有误, 准确的表达应该是:局部变量表所需的内存在编译期就已经计算完成(即需要在运行时分配多大内存)。
判断对象是否已死(可以回收)的算法
从永久代到年轻代的引用可以被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉
方法区(永久代)回收的相关说明:
永久代的垃圾回收主要两部分内容:废弃的常量和无用的类。 废弃的常量:无任何对象引用此常量。 无用的类:、该类所有实例已经被回收(堆中不存在该类的任何实例)。
、加载该类的ClassLoader已经被回收。
、给类对应的Class对象没有任何地方呗引用,无法在任何地方通过反射访问该类的方法
垃圾收集的算法:
1、标记 - 清除算法
包含标记和清除2个阶段,是最基础的算法。标记就是标记出那些已经可以被回收的对象,在标记完成后进行清楚,此算法效率不高而且会产生内存碎片,当程序在以后的运行中需要分配一块大的连续的内存时可能因为内存碎片的问题而提前触发再次垃圾回收。
过程示意图如下:
2、复制算法(新生代采用的算法之一)
为了解决标记-清除 算法 的效率问题的,将内存划为多块,在标记完一块区域的对象的存活状态后,将存活的对象拷贝到另外一块上,然后将之前的那块一次清理掉。
在新生代上对象存活期很短,并且98%的对象是朝生夕死,所以在内存的划块上不需要1:1进行划分,hotspot虚拟机默认按照Eden-80%,两块Survivor各10%进行划分(8:1),其中Eden和一块Survivor空间用来存放新生代的对象,还有一块用来复制垃圾回收时Eden和另外一块Survivor的存活对象,然后一次清除调用Eden和那块Survivor内存,下次垃圾回收时这2块Survivor的功能互相调换。当一块Survivor不够装下存活的对象时,则会向老年代的分配担保机制(借内存)进入到老年代。
复制算法的示意图:
3、标记 - 整理算法
相比标记-清理算法,此算法解决了标记-清理算法的内存碎片问题,清理完可回收的对象后会对该内存块进行整理。
算法示意图:
4、分代收集算法
当前商业虚拟机都采用此算法,其实说这是算法还不如说是一个将前面3个算法在新生代和老年代上应用不同算法的一个策略,新生代采用复制算法,老年代采用“标记-清除”或者“标记-整理”算法。
垃圾回收器(垃圾收集算法的具体实现)
HotSpot 1.6版Update22的收集器入下所示:
上面部分是新生代的垃圾回收器,下面部分是老年代的垃圾回收器,中间的连线表示这2个回收器可以配合一起使用。
新生代的垃圾收集器
1、Serial收集器(复制算法)
此收集器是最基本的,也是历史最悠久的收集器,是JDK1.3.1之前新生代的唯一选择,该收集器的缺点是垃圾收集器回暂停用户的所有线程来进行单线程的垃圾收集,后面的其它收集器基本就是在此收集器的基础进行优化修改而来,在Client模式下运行还是可以的接受的。
运行示意图如下:
2、ParNew收集器(复制算法)
Serial的多线程版本,是许多运行在Server模式下的虚拟机中新生代收集器的首选。在多核心的服务器上运行优势明显,默认开启的线程=CPU核心数,
通过使用-XX:ParallelGCThreads参数可以来限制垃圾收集的线程数。
运行示意图:
3、Parallel Scavenge收集器(复制算法)
跟parNew收集器差不多,但与上面2个收集器的关注点不同,前面的2个更多的关注用户的停顿时间,而此收集器更关注CPU的吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)),
其中有2个参数可以控制这个吞吐量,1、-XX:MaxGCPauseMillis xxxx,控制最大垃圾收集停顿时间(x>0的毫秒数)。2、-XX:GCTimeRatio XXX,设置吞吐量大小(设置一个0<x<100的整数,表示垃圾收集器时间占总时间的比率,相当于吞吐量的倒数)。
另外,此收集器还有一个参数-XX:+UseAdaptiveSizePolicy,如果打开这个开发,则新生代的大小(-Xmn)、Eden、Survivor(-XX:SurvivorRatio)、晋升老年代的对象年龄(-XX:PretenureSizeThreshold)等参数就不需要手工指定了,虚拟机会根据系统的运行情况来动态调整。
运行示意图:
老年代收集器
1、Serial Old收集器(标记-整理算法)
新生代serial的老年代版本,主要有如下2个用途:1、在JDK1.5以及之前的版本搭配新生代的Parallel Scavenge收集器使用。2、作为CMS收集器发生Concurrent Mode Failure的一个后备方案。
2、Parallel Old收集器(标记-整理算法)
新生代Parallel Scavenge收集器的老年代版本,在JDK1.6的版本中才提供,只能和新生代的Parallel Scavenge收集器搭配使用。
3、CMS收集器(标记-清除算法)
Concurrent Mark Sweep,一种以获取最短回收停顿时间为目标的收集器,具有并发低顿挫的特点,但其也有几个缺点:
①对CPU资源很敏感(需要跟用户线程并发执行)。
②无法处理浮动垃圾(Floating Garbage,在标记过程后产生的垃圾),CMS需要预留足够的内存空间给用户线程使用,所以CMS收集器在老年代使用了68%的空间后被激活(可以通过-XX:CMSInitiatingOccupancyFranction参数来配置触发百分比),如果在运行过程中预留的内存无法满足程序需要,则会出现一次“Concurrent Mode Failure”失败并启用后备预案(Serial Old收集器)进行Full GC。
③由于采用标记-清除算法,会产生内存碎片,不过可以配置-XX:+UseCMSCompactAtFullCollection开关让Full GC后进行一次碎片整理,也可以使用-XX:CMSFullGCsBeforeCompaction来设置执行多少次Full GC自动来一次碎片整理。
共分为4个过程:
㈠、初始标记
需要暂停用户线程,但过程很快。
㈡、并发标记
㈢、重新标记
需要暂停用户线程,对前面的标记进行修正。
㈣、并发清除
运行示意图:
4、G1收集器
Garbage First收集器是当前收集器技术发展的前沿成果,在JDK1.6_update14提供试用,是一款面向服务器应用的垃圾收集器。
主要有如下特点:
● 并发运行
● 基于标记-整理算法,不会产生空间碎片
● 非常精确的控制停顿,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在收集上的时间不超过N毫秒,这几乎是实时JAVA(RTSJ)垃圾收集器的特征了
● 将整个堆(新生代、老年代)划分为多个大小固定的独立区域,并与这些区域为单位进行垃圾回收,避免对整个堆进行全量回收操作,并对这些区域进行优先级维护和回收。
进入老年代的几种途径
1、在新生代GC过程中survivor空间不够,通过老年代的分配担保机制提前转入老年代。
2、超过参数PretenureSizThreshold设置的值的大对象直接进入老年代,所谓大对象就是需要大量连续内存空间的java对象(例如很长的字符串和大数组)。
3、长期存活的新生代对象进入老年代,如果对象在一次Minor GC(新生代GC)后仍存活并且能被survivor容纳后被移动到Survivor中后将该对象的年龄+1,当它的年龄达到一定程 度(默认15)后就会晋升到老年代,这个阀值可以通过-XX:MaxTenuringThreshold来设置。
4、虚拟机并不总要求对象达到XX:MaxTenuringThreshold的值后才晋升老年代,如果在Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一半,年龄大于或者等于 该年龄的对象就可以直接进入老年代。
JAVA内存模型及垃圾回收自我总结的更多相关文章
- Java内存模型与垃圾回收
1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法 ...
- java内存模型和垃圾回收(收藏)
java内存模型: https://www.cnblogs.com/handsomeye/p/5442879.html java垃圾回收 http://www.cnblogs.com/handsome ...
- Java内存模型与垃圾回收笔记
内存模型 栈. 局部变量(基本类型)与对象引用:线程隔离.每个方法执行时会创建一个栈帧,存储局部变量等. 堆. 对象实例:线程共享. 方法区.类信息.常量(final).静态变量.符号引用: 线程共享 ...
- java内存模型和垃圾回收
摘抄并用于自查 JVM内存模型 1. Java程序具体执行的过程: Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀) 由JVM中的类加载器加载各个类的字节码文 ...
- Java虚拟机内存模型及垃圾回收监控调优
Java虚拟机内存模型及垃圾回收监控调优 如果你想理解Java垃圾回收如果工作,那么理解JVM的内存模型就显的非常重要.今天我们就来看看JVM内存的各不同部分及如果监控和实现垃圾回收调优. JVM内存 ...
- 【Java_基础】JVM内存模型与垃圾回收机制
1. JVM内存模型 Java虚拟机在程序执行过程会把jvm的内存分为若干个不同的数据区域来管理,这些区域有自己的用途,以及创建和销毁时间. JVM内存模型如下图所示 1.1 程序计数器 程序计数器( ...
- 程序猿的日常——JVM内存模型与垃圾回收
Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础--这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...
- JVM内存模型和垃圾回收
Java开发有个很基础的问题,虽然我们平时接触的不多,但是了解它却成为Java开发的必备基础——这就是JVM.在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情 ...
- (转载)JVM中的内存模型与垃圾回收
转载自微信公众号:Java高级架构(Java-jiagou)-----看完这篇文章,我奶奶都知道JVM中的内存模型与垃圾回收了! 六.内存模型 6.1 内存模型与运行时数据区 Java虚拟机在执行J ...
随机推荐
- cannot be resolved. It is indirectly referenced from required .class files
缺少引用. 把缺少的引用在导入一下...如果是mavan 在当前moudle里也要把 dependency加进来
- @ZooKeeper注册中心安装(单节点)
1.下载zookeeper 下载地址:https://archive.apache.org/dist/zookeeper/,这里我们使用3.4.6版本. [winner-0715@localhost ...
- IDEA远程debug的使用
1.打开配置页面 2.添加远程调试配置 3.进行参数配置 不同的jdk版本,配置的参数是不一样的! 其中Host为远程服务器的地址,Port为远程debug的端口,注意要与前面设置的address保持 ...
- bash 括号(小括号,双小括号,中括号,双中括号,大括号)
小括号()和大括号{} 主要包括一下几种 ${var} $(cmd) ()和{} $((exp)) ${var:-string},${var:+string},${var:=string},${var ...
- 东芝发布运行Win 10的AR眼镜,它和Google Glass企业版有哪些异同?
https://www.leiphone.com/news/201803/Tw0nrq6vGDIvbmXr.html 雷锋网(公众号:雷锋网)获悉,3月13日,东芝发布新AR眼镜dynaEdge AR ...
- libnids
一.简介 libnids的英文意思是 Network Intrusion Detect System library,即网络入侵监测系统函数库.它是在前面介绍的两种C函数接口库libnet和libpc ...
- android api doc 一
Manifest.permission 用于记录相应权限类 ACCESS_CHECKIN_PROPERTIES 允许在登入数据库的时候读写其中的属性表,并上传改变的值 ACCESS_COARSE_LO ...
- CentOS下ssh sftp配置及权限设置
运营有异地传输文件的需求,但如果通过QQ等即时通讯软件,不利于文件的集中管理,不方便.而我们办公室的内网机器无法提供外网访问方法,且传输的内容不合适放到公共的网盘或者是云存储上,所以只能用线上负载较低 ...
- 转:使用RNN解决NLP中序列标注问题的通用优化思路
http://blog.csdn.net/malefactor/article/details/50725480 /* 版权声明:可以任意转载,转载时请标明文章原始出处和作者信息 .*/ author ...
- how-to-get-a-job-in-deep-learning
http://blog.deepgram.com/how-to-get-a-job-in-deep-learning/ How to Get a Job In Deep Learning 22 SEP ...