博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于JVM内存区域的组成以及堆内存的回收原理
阅读量:4189 次
发布时间:2019-05-26

本文共 2657 字,大约阅读时间需要 8 分钟。

关于JVM内存区域的组成以及堆内存的回收原理

JVM内存区域的组成。

jvm的运行是依赖于内存空间,就好比是操作系统的运行是需要内存的,我们大家都有体会,当我们电脑运行的程序越来越多的情况下,突然在某一个时刻,你点击了某个操作,操作系统半天没有反映,然后再去看一下操作系统的内存占用情况,发现内存的使用已经高达百分之九十以上了。这个时候,操作已经没有内存去做剩下的操作了。jvm也是一样,jvm的运用也需要内存去支撑它的操作。

jvm运行的依赖内存空间:我们称之为运行时数据区域,运行时数据区域分为如下几个部分:

第一部分:java栈内存(虚拟机栈内存),该内空间主要是用来存储基本类型和他的值(例如,int ,short,double等等),运算符号(加减乘除),以及一些指向对象的内存引用。(一般栈空间的大小平均分配4KB),方法里面的属性如果是类类型,引用再栈,值再堆里面。

第二部分:java堆内存,该内存空间主要是用存储真正的java对象的,例如对象的属性值。

第三部分:方法区(永久代或者元空间是方法区的实现), 该内存空间是用来类中的方法描述的。以及一些静态变量值,长量值,以及类的定义。

第四部分:本地方法栈,该内存空间主要用来存取本地方法执行栈片帧的,以及参数值

第五部分:程序计数器:该内存占用很小的内存,可以忽略不计,该内存主要用来记住程序执行到类的那一行了。我们程序抛异常,会确定异常到底抛在类的那一行。

jvm抛出的栈内存异常的分析:StackOverFlowError.很大可能是JAVA方法栈里面堆积了太多的栈帧。例如,一个递归运算,如果没有结束条件的话,很容易引爆方法栈内存异常的。

JVM的堆内存异常的分析:

java的堆内存,主要是用来存对象真正的数据,一般一个对象的堆内存平均只分配8KB。1KB == 1024B(B:就是字节),说明一个对象可以存8192字节。一个字符一个字节。一个对象可以存8129个字符。

java堆内存的组成:java堆内存主要三个部分组成(年青代(伊甸园区,存活区(S0,S1)),老年代,永久代(jdk1.8之后,包含jdk1.8.就没有永久代,改变成元空间了))

这里我想解释一下:为什么jdk1.8之后,把永久带变成了元空间了,因为再jvm的发展史上,以前是有三个主流的JVM,一个是sun公司的HotSpot. 一个是BEA公司的,JRockit, 其次就是IBM的JVM‘S(也叫J9).近些ORACLE这个牛叉的公司竟然把SUN和BEA给收购了,让他们给自己打工。但是ORACLE这个老板不傻阿,这两个公司都有自己JVM,如果他们还各自研发自己的JVM,那我不是付了两分钱,干同样的事。因此,ORACLE公司,就需要将SUN 和BEA的JVM给整合。所以就出现了元空间这个概念了。元空间和永久代的存储功能还是一样的,都是用来用存方法里面的局部变量的,不过之间还是有差别的,永久代用的堆内存,而元空间用的JVM内存之外的物理内存。

JRockit 和 J9不存在永久代,永久代是存在HotSpot中的概念。

java堆内存垃圾回收的机制:我们清楚了堆内存分了几个区域,

第一部分:是伊甸园区,伊甸园区主要用来存放新建的对象。首先在我们新建一个对象的时候,我们就会来判断伊甸园区的内存是否充足,如果充足,就存这个新建的对象,如果不充足,也不要着急,我先启动我们的Minor GC,进行一次垃圾回收。当Minor GC之后,伊甸园区的内存还是不足的情况下该怎么办了,难道对象就创建不了吗,请看第而部分。

第二部分:当伊甸园区的经过年轻代垃圾回收之后,还是内存不足的情况下,JVM就会扫描存活区的内存是否充足,如果存活区的内存充足,就把伊甸园区部门存活的对象拷贝到存活区,最后伊甸园区就足够的内存空间存储新对象了。如果扫描存活区,发现了存活区的内存不足的化,这个时候就需要走到第三部分拉。

第三部分:存活区也没有内存空间的前提下,jvm就开始扫描老年代的内存空间,如果老年代的内存空间充足的情况下,就会把存活区的活动对象拷贝到老年代,伊甸园区的活动对象拷贝到内存存活区,最后新对象被创建保存在伊甸园区。如果老年代内存不足的情况下,不足应该咋办了。第四部分见分晓。

第四部分,当老年代的内存不足的情况,那么就需要开始Major GC 回收机制。如果Major GC过后,老年代空间充足,那么就会把存活区的部分对象拷贝到老年代,把伊甸园区的部分活动对象拷贝到存活区,最后伊甸园区就会内存空间,进行新对象的创建。如果垃圾回收过后,还是内存不做。

第五部分,MajorGC过后,内存还是不足,那么这时候,就需要报Heap OutOfMemoryError.

关于MajorGC和FullGC的触发

触发MinorGC(Young GC)

虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间
1、如果大于的话,直接执行minorGC
2、如果小于,判断是否开启HandlerPromotionFailure,没有开启直接FullGC
3、如果开启了HanlerPromotionFailure, JVM会判断老年代的最大连续内存空间是否大于历次晋升的大小,如果小于直接执行FullGC
4、如果大于的话,执行minorGC
触发FullGC
老年代空间不足
如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。
持久代空间不足
如果有持久代空间的话,系统当中需要加载的类,调用的方法很多,同时持久代当中没有足够的空间,就出触发一次Full GC
YGC出现promotion failure
promotion failure发生在Young GC, 如果Survivor区当中存活对象的年龄达到了设定值,会就将Survivor区当中的对象拷贝到老年代,如果老年代的空间不足,就会发生promotion failure, 接下去就会发生Full GC.
统计YGC发生时晋升到老年代的平均总大小大于老年代的空闲空间
在发生YGC是会判断,是否安全,这里的安全指的是,当前老年代空间可以容纳YGC晋升的对象的平均大小,如果不安全,就不会执行YGC,转而执行Full GC。显示调用System.gc

转载地址:http://gusoi.baihongyu.com/

你可能感兴趣的文章
IT治理的成功要诀
查看>>
中化CIO彭劲松:IT治理让我明明白白做事
查看>>
中国惠普公司企业计算及专业服务集团卫东:IT治理最重要就是保证技术与业务有效结合
查看>>
【MVP】 Wenzhong Huang 北大硕士,微软MVP,微软嵌入式讲师,MCSE
查看>>
解析ERP部署的三角模型
查看>>
百感交集:一个IT人应该如何面对失业?
查看>>
服装经营中关于直销、加盟、代理和联营的区别
查看>>
盯上好男人 服装业B2C暗战
查看>>
局域网内部管理行为应该如何控制?
查看>>
CIO--成,获得认可;败,危及部门生存
查看>>
ERP专家童継龙:ERP从神秘少女变成邻家小妹
查看>>
Palm之祭
查看>>
两种不同的Web应用
查看>>
.Net多线程总结(一)
查看>>
让 ASP.NET MVC 支持 HotSwap
查看>>
Http请求处理流程
查看>>
如何利用客户端缓存对网站进行优化?
查看>>
ASP.NET 应用程序性能优化
查看>>
lr监视的性能计数器
查看>>
优化 SQL Server 查询性能
查看>>