文档章节

JVM堆的理解

 不羁之后
发布于 06/19 23:30
字数 1584
阅读 11
收藏 0
点赞 0
评论 0

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图:

 

大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常有用的,在这里面了解JVM的GC原理,是非常重要的一块知识。 我们都知道对于一个大型网站,如果JVM频繁发生FULL GC,那么将会是致命的危险,不仅仅会造成网站响应迟钝,更严重的时候会导致系统崩溃,这对用户体验来讲,都是我们不愿意看到的。

在JVM里的内存空间,从大的层面划分,主要有新生代空间(Young)和老年代空间(Old),其中Young空间,又被分为2个部分和3个板块,分别是1个Egen区,和2个Survivor区,看下图:

 

OK,下面来具体看下,每部分都是干啥的

(1)Eden区域是用来存放使用new或者newInstance等方式创建的对象,默认都是存放在Eden区,除非这个对象太大,或者超过了设定的阈值-XX:PretenureSizeThresold,这样的对象会被直接分配到Old区域。

(2)2个Survivor(幸存)区,一般称S0,S1,理论上他们是一样大的,解释一下,他们是如何工作的:

在不断创建对象的过程中,Eden区会满,这时候会开始做Young G也叫Minor GC,而Young空间的第一次GC就是找出Eden区中,幸存活着的对象,然后将这些对象,放到S0,或S1区中的其中一个, 假设第一次选择了S0,它会逐步将活着的对象拷贝到S0区域,但是如果S0区域满了,剩下活着的对象只能放old区域了,接下来要做的是,将Eden区域 清空,此时时候S1区域也是空的。

当第二次Eden区域满的时候,就将Eden区域中活着的对象+S0区域中活着的对象,迁移到S1中,如果S1放不下,就会将剩下的部门,放到Old区域中,只是这次对象来源区域增加了S0,最后会将Eden区+S0区域,清空

第三次和第四次依次类推,始终保证S0和S1有一个是空的,用来存储临时对象,用于交换空间的目的,反反复复多次没有被淘汰的对象,将会放入old区域中,默认是15次。具体的交换过程就和上图中的信息相似。

问题一:怎么定义活着的对象?

从根引用开始,对象的内部属性可能也是引用,只要能级联到的都被认为是活着的对象

问题二:什么是根?

本地变量引用,操作数栈引用,PC寄存器,本地方法栈引用等这些都是根。

问题三:对象进入Old区域有什么坏处?

old区域一般称为老年代,老年代与新生代不一样,年轻代,我们可以认为存活下来的对象很少,而老年代则相反,存活下来的对象很多,所以JVM的 堆内存,才是我们通常关注的主战场,因为这里面活着的对象非常多,所以发生一次FULL GC,来找出来所有存活的对象是非常耗时的,因此,我们应该尽量避免FULL GC的发生。

问题四:S0和S1一般多大,靠什么参数来控制,有什么变化?

一般来说很小,我们大概知道它与Young差不多相差一倍的比例,设置的的参数主要有两个:

-XX:SurvivorRatio=8

-XX:InitialSurvivorRatio=8

第一个参数是Eden和Survivor区域比重,注意是一个Survivor的的大小,如果将其设置为8,则说明Eden区是一个Survivor区的8倍,换句话说S0或S1空间是整个Young空间的1/10,剩余的80%由Eden区域来使用。

第二个参数是Young/S0的比值,当其设置为8时,表示s0或s1占整个Young空间的12.5%。

问题五;一个对象每次Minor Gc时,活着的对象都会在s0和s1区域转移,经过经过Minor GC多少次后,会进入Old区域呢?

默认是15次,参数设置-XX:MaxTenuringThreshold=15,计数器会在对象的头部记录它交换的次数

问题六:为什么发生FULL GC会带来很大的危害?

在发生FULL GC的时候,意味着JVM会安全的暂停所有正在执行的线程(Stop The World),来回收内存空间,在这个时间段内,所有除了回收垃圾的线程外,其他有关JAVA的程序,代码都会静止,反映到系统上,就会出现系统响应大幅度变慢,卡机等状态。

举个通俗易懂点的例子,就是在一个房间里,如果有一个人,不停的扔垃圾,然后有一个清洁工不停扫垃圾,这时候,我们的系统是OK的,因为基本不会 出现垃圾堆满房间的情景,而且因为清洁工可以对付过来,假设现在有10个人不停扔垃圾,那么就房间就会很快被堆满,这时候清洁工,由于工作不过来了,大声 吼一声,你们都暂停3分钟,别再扔了,我先把这个房间打扫完,你们才可以扔。

在这个场景中,一个人扔,一个人扫,就类似于Minor GC,这时候,并不会影响扔垃圾的人,然后一旦10个人同时仍,而且很快就没地方仍了,这时候,就会触发Full GC,然后JVM下令,你们暂时都别仍了,等我什么时候回收完垃圾了,你们在仍,现在大家清楚了吧,所谓的10个人,就是类似我们成千上百的java类, 在不停的执行任务,所谓的清洁工,就是我们的GC机制,所以,大家在平时编码的时候,一定注意尽量少造点垃圾对象,这样触发FULL GC的几率,才会变小。

© 著作权归作者所有

共有 人打赏支持
粉丝 1
博文 35
码字总数 23075
作品 0
成都
《成神之路-基础篇》JVM——JVM内存结构(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 参考文章: Java虚拟机的内存组成以及堆内存介绍 Java堆和栈...

05/05
0
0
JVM基础:深入学习JVM堆与JVM栈

以前堆是干啥栈是干啥都知道,就是没连在一起想想。感觉讲的不错的一篇儿~~JVM栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;JVM堆解决的是数据存储的问题,即数据怎么放、放在...

李星
2014/06/04
0
0
JVM 运行时数据区简介及堆与栈的区别

理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机制,...

大数据之路
2015/08/02
0
1
Java堆和栈的区别和介绍以及JVM的堆和栈

Java堆和栈的区别和介绍以及JVM的堆和栈 一、Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存。 堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个...

代金券优惠
05/24
0
0
Java堆和栈的区别,JVM的堆和栈的介绍

一、Java的堆内存和栈内存 Java把内存划分成两种:一种是堆内存,一种是栈内存。 堆:主要用于存储实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的...

光明辉煌
05/21
0
0
My java——JVM(内存域)三

续 My java——JVM(内存)二 写了一点JVM内存的一些操作的方法,和引出内存的分类。 是呀,java内存是我们在java编程中很少考虑到的,也没用真正的管理过。也许都知道JVM有自己的垃圾回收机...

tngou
2013/03/18
0
0
Java虚拟机运行时数据区结构

本文部分参考自《Java虚拟机规范(Java SE 7版)》的中译本和周志明的《深入理解Java虚拟机》,另加个人理解。原书对Java虚拟机运行时数据区描述只有6页,同时参考其他网络网资料,个人能力所...

foodon
2014/12/09
0
4
【JVM】 java内存区域与内存溢出异常

前言 此系列博客是读《深入理解java虚拟机》所做的笔记整理。 No1. JVM内存管理这堵墙? 对C和C++的开发人员来说,在内存管理领域,他们既拥有每一个对象的“所有权”,也担负着每一个对象生...

binggetong
05/07
0
0
Java并发(1)- 聊聊Java内存模型

引言 在计算机系统的发展过程中,由于CPU的运算速度和计算机存储速度之间巨大的差距。为了解决CPU的运算速度和计算机存储速度之间巨大的差距,设计人员在CPU和计算机存储之间加入了高速缓存来...

knock_小新
昨天
0
0
[转]Java虚拟机支持的最大内存限制

在命令行下用java -XmxXXXXM -version命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息。 下面列出当前比较流行的几个不同公司不同版本J...

mj4738
2012/05/22
0
4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vue-router懒加载

1. vue-router懒加载定义 当路由被访问的时候才加载对应组件 2. vue-router懒加载作用 当构建的项目比较大的时候,懒加载可以分割代码块,提高页面的初始加载效率。 ###3. vue-router懒加载实...

不负好时光
12分钟前
0
0
庆祝法国队夺冠:用Python放一场烟花秀

天天敲代码的朋友,有没有想过代码也可以变得很酷炫又浪漫?今天就教大家用Python模拟出绽放的烟花庆祝昨晚法国队夺冠,工作之余也可以随时让程序为自己放一场烟花秀。 这个有趣的小项目并不...

猫咪编程
14分钟前
0
0
SpringBoot | 第七章:过滤器、监听器、拦截器

前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息、统计在线人数、在线用户数、过滤敏高词汇、访问权限控制(URL级别)等业务需求。这些对于业务来说一般上是无关的,业务方是无需...

oKong
28分钟前
4
0
存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储 存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储。 顺序结构和链接结构适用在内存结构中。 顺序表每个单元都是按物理...

DannyCoder
38分钟前
1
0
Firefox 61已经为Ubuntu 提供支持

最新和最好的Mozilla Firefox 61 “Quantum”网络浏览器已经为Ubuntu Linux操作系统的用户提供了支持,现在可以通过官方软件库进行更新。 Mozilla于2018年6月26日发布了Firefox 61版本,该版...

六库科技
今天
0
0
Win10升级后执行系统封装(Sysprep)报错

开始封装 一年多以前开始给公司封装Win10系统,便于统一给公司电脑初始化携带各种软件的系统,致力于装完既可以开发的状态。那时候最新的版本是Win10 1703版本,自然就以他为母盘,然后结合V...

lyunweb
今天
40
0
php 性能优化

#什么情况下会遇到性能问题 PHP 语法使用的不恰当

to_be_better
今天
0
0
Jenkins 构建触发器操作详解

前言 跑自动化用例每次用手工点击jenkins出发自动化用例太麻烦了,我们希望能每天固定时间跑,这样就不用管了,坐等收测试报告结果就行。 一、定时构建语法 * * * * * (五颗星,中间用空格隔...

覃光林
今天
0
0
IDEA配置技巧

超详细设置Idea类注释模板和方法注释模板 idea去掉注解param下划线 JetBrains全系列破解

AK灬
今天
0
0
rsync通过服务同步/Linux系统日志/screen工具

rsync通过服务同步 分为服务端(机器A) 和客户端(机器B) 机器A操作编辑/etc/rsyncd.conf配置文件 [root@yolks1 ~]# vim /etc/rsyncd.conf 文件中添加以下配置 port=873 ...

Hi_Yolks
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部