JVM内存区域划分及垃圾回收
第一部分、闲扯+概述
近来在研读《深入理解java虚拟机》一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕。
要理解JVM,就要先从其内存区域划分开始,知道其由几部分构成,再了解各部分的功能,这样就能对其整体有一个了解。
话不多说,总体图先呈上:
可以看到,线程私有的内存区域有虚拟机栈、本地方法栈、程序计数器,这些区域都不会出现线程安全问题;而线程共享的区域有堆、方法区。
下面对其各个分区域进行介绍。
第二部分:JVM内存区域划分
1、首先是最简单的程序计数器,每个线程都有一个独立的计数器,用来记录线程执行的虚拟机字节码指令。另外,如果是Native方法,则计数器中的
值为undifined。
2、本地方法栈:类似于虚拟机栈,只是此处运行的是native方法
3、虚拟机栈:运行java方法的地方,基本单位是栈帧,一个方法从开始执行到结束的过程,就是一个栈帧在虚拟机栈中入栈到出栈的过程。(本来
认真准备了两张栈帧跟局部变量表的逻辑示意图,不知道怎么的传不上来,只能省去,<手动擦汗>)
3.1、局部变量表:顾名思义,是存返方法中变量的地方。
局部变量表存放变量的单位是Slot 槽,每个槽都能存放一个32位的变量,64位的由连续的两个槽来存放。如果执行的是非static方法,则第一个槽中
存放的是当前对象的引用,即this。具体存放的引用,是直接或间接能定位到这个对象在堆中的位置的一个值,比如对象的起始地址。
3.2、操作数栈:是LIFO(后入先出)栈,虚拟机就是一个基于操作数栈的执行引擎。在处理数据中处于重要位置。一个32位的数据占据栈中一个容量。比如执行a+b时,字节码
指令会先往栈中压入a跟b,然后iadd指令执行时,将栈顶的两个值a跟b弹出,相加,再压入栈中,完成计算。
3.3、动态链接:存放的是方法区的运行时常量池中此栈帧对应的方法的引用
3.4、返回地址:记录方法执行完之后返回的位置,回到这个位置程序才能正确的继续执行下去。
4、方法区:最主要的功能,便是存放字节码文件、Class对象、常量等
5、堆区:此部分是虚拟机中上连栈下连方法区的中枢之地,也是垃圾收集的重地,可以说基本所有的对象都存放在此区域。
对象在堆区中,由三部分组成:对象头、实体数据、对齐填充
对象头:一般由两部分组成,一部分是用于存放hash值、分代年龄、锁标识的称为Mark Word的区域,另一部分用于存放指向方法区中对象类型的指针(直接指针定位时有);
实体数据:存放正常的对象数据;
对齐填充:对象的内存占用大小为8字节的整数倍,如果不够,用此部分来填充。
堆区按照垃圾收集区域,划分为两部分:新生代、老年代,一般默认比例是1:2,而在新生代中,又分成了三部分,分别为Eden、Survivor From 、Survivor To ,默认比例
为8:1:1。
第三部分、垃圾回收
触发条件:当内存中可用空间不够时才会触发垃圾回收
什么样的对象会被回收:通过可达性分析算法,如果发现某个对象与GC ROOTS没有连接,则此对象满足被回收的条件。
GC ROOTS定义:1) 虚拟机栈中引用的对象;2)本地方法栈中引用的对象;3) 类静态属性引用的对象;4) 常量引用的对象
如何回收:标记清除算法、复制算法、标记整理算法、分代搜集算法,目前主流虚拟机中使用的就是分代搜集算法
分代搜集算法的过程:JVM开发团队发现,对于新生代中大部分的对象,存活时间都很短,所以新生代使用复制算法,且工作空间与空闲空间之比为9:1(9即上面所说的一个
Eden与Survivor From之和),因为新生代绝大部分对象会被清理,清理之后还剩下的对象就放在那一份的Survivor To中,如果空间不够,再往老年代放,另外经历过一定次数的
新生代处理还没被回收的对象,也会转移到老年代中;而对于老年代,用标记整理算法或者标记清除算法,因为老年代对象数量庞杂,且大多数不满足清理条件,所以老年代的
垃圾回收耗时长效果相对较差。新生代中Eden区域专门用于存放新对象,如果此区域内存空间不足,则触发新生代GC,此之谓Minor GC;同样老年代空间不足,触发Full GC(亦
称之为Major GC),耗时长,要尽量避免,一般来说Full GC次数一天不能超过一次。
垃圾收集器:针对新生代跟老年代都有不同的垃圾搜集器,例如针对新生代的有Serial、ParNew等,针对老年代的有CMS、Serial Old等,不同的搜集器之间只能有特定的
几个组合(不能随意地组合使用,会有不兼容),具体看项目实际情况而定。目前BZ所在公司用的是ParNew与CMS的组合,虽然CMS用的是标记清除算法,会使垃圾收集后的内存
碎片较多,但是万能的前辈们早就想到了这些,提供了-XX:+UseCMSCompactAtFullCollection指令压缩内存中的碎片,以及-XX:CMSFullGCsBeforeCompaction指令设置多少次
Full GC后整理内存碎片。
针对垃圾收集这一块,BZ还没有实际动手通过相关知识解决过项目中的问题,目前只是纸上谈兵,后面会摸索一下如何通过工具监控项目中的内存状况,并整理出来。学习之
路,还是要多给自己打打鸡血~
JVM内存区域划分及垃圾回收的更多相关文章
- JVM的内存区域划分以及垃圾回收机制详解
在我们写Java代码时,大部分情况下是不用关心你New的对象是否被释放掉,或者什么时候被释放掉.因为JVM中有垃圾自动回收机制.在之前的博客中我们聊过Objective-C中的MRC(手动引用计数)以 ...
- JVM内存管理机制和垃圾回收机制
JVM内存管理机制和垃圾回收机制 JVM结构 图片描述: java源码编译成class文件 class文件通过类加载器加载到内存 其中方法区存放的是运行时的常量.静态变量.类信息等,被所有线程共享 堆 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
以下内容转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29632145&id=4616836 jvm区域总体分两 ...
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释(转)
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分Eden Space,Survivor Space,Tenured Gen,Perm Gen
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存模型和GC垃圾回收
JVM 内存区域 1.程序计数器 这是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器,指的是上次代码被执行的地方,线程私有. 2.Java 虚拟机栈 它是 Java方法执行的 ...
- [转]JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...
- JVM内存区域划分
前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...
- JVM内存区域划分(JDK6/7/8中的变化)
前言 Java程序的运行是通过Java虚拟机来实现的.通过类加载器将class字节码文件加载进JVM,然后根据预定的规则执行.Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同 ...
随机推荐
- Linux系统minicom命令详解
minicom 功能说明:调制解调器通信程序 语 法:minicom [-8lmMostz][-a<on或0ff>][-c<on或off>][-C<取文件>][-d ...
- 微擎开发------day02
基本要素: 微擎系统数据库操作使用PDO兼容方式,参数绑定进行查询操作 (1) 数据表加上表前缀 $sql = "select * from ".tablename('users ...
- PHP开发——超全局数组变量
概述 l JS中的变量分两类:局部变量.全局变量. l PHP中的变量分三类:局部变量.全局变量.超全局变量. l 局部变量:在函数内部声明的变量,就是局部变量.函数执行完毕,局部变量就消失了. ...
- Map 数据结构
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键.这给它的使用带来了很大的限制. 为了解决这个问题,ES6 提供了 Map 数据结构. ...
- vnc 搭建 转
这里要注意,关闭selinux setenforce 0 原文地址: http://www.linuxidc.com/Linux/2015-04/116725.htm 这是一个关于怎样在你的 Cent ...
- KD-树(上)
来自于https://zhuanlan.zhihu.com/p/23966698 思路篇 导语:kd 树是一种二叉树数据结构,可以用来进行高效的 kNN 计算.kd 树算法偏于复杂,本篇将先介绍以二叉 ...
- CDH版本的hadoop下载
http://archive.cloudera.com/cdh5/cdh/5/加要下载的cdh版本插件 例如: http://archive.cloudera.com/cdh5/cdh/5/zooke ...
- ActiveMQ_2安装
Linux安装 环境JDK7以上 gz文件拷贝到 /usr/local/目录下 解压 后缀为 .tar.gz的压缩包 进入解压后的文件夹 cd apache-activemq-x.xx.x/ cd b ...
- 第35章:MongoDB-集群--Master Slave(主从复制)
①主从复制 最基本的设置方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址.采用双机备份后主节点挂掉了后从节点可以接替主机继续服务,所以这种模式比单节点的高可用性要好很多. ②注意 ...
- Struts2学习第四天——全局结果,动态结果及异常映射
1.异常映射的配置 当Action方法出错时Struts会返回异常错误信息页面,这种页面方式是不友好的,可以使用try-catch捕捉异常,然后在catch块中返回对应的错误页面.这种为单个<a ...