文档章节

JVM堆的理解

 不羁之后
发布于 06/19 23:30
字数 1584
阅读 17
收藏 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的几率,才会变小。

© 著作权归作者所有

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

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

05/05
0
0
java 基本数据类型各种情况下在内存中存储位置?

问题: 如何理解《Java编程思想-第四版》P23 中 这个变量直接存储“值”,并置于堆栈中,因此更加高效 一句中的 “堆栈” 两字,到底是堆还是栈? 情况如下: 参考《Java编程思想-第四版》P...

lihuayang
2016/12/29
693
5
My java——JVM(内存域)三

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

tngou
2013/03/18
0
0
JVM基础:深入学习JVM堆与JVM栈

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

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

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

大数据之路
2015/08/02
0
1

没有更多内容

加载失败,请刷新页面

加载更多

【Flutter教程】从零构建电商应用(一)

在这个系列中,我们将学习如何使用google的移动开发框架flutter创建一个电商应用。本文是flutter框架系列教程的第一部分,将学习如何安装Flutter开发环境并创建第一个Flutter应用,并学习Flu...

笔阁
26分钟前
5
0
什么是以太坊DAO?(三)

Decentralized Autonomous Organization,简称DAO,以太坊中重要的概念。一般翻译为去中心化的自治组织。 投票支付合约的所有费用和行动需要时间,并要求用户始终保持活跃,知情和专注。另一...

geek12345
27分钟前
2
0
一个本科学生对Linux的认知

一个本科学生对Linux的认知 我是一名大三的普通一本大学的软件工程的一名学生,学校开设了一些关于系统开发的课程,纸上得来终觉浅,学校的课程课时较短,想要在56个课时之内学会一些公司需要...

linuxCool
今天
3
0
CentOS 安装Tomcat

Tomcat 介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 Java 程序写的网站用tomcat+jdk来运...

野雪球
今天
1
0
OSChina 周四乱弹 —— 每天都迟到是种什么样的体验

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @开源中国首席机器人 :《Too Good At Goodbyes (Acoustic) - Sam Smith - 单曲》 《Too Good At Goodbyes (Acoustic) - Sam Smith - 单曲》 ...

小小编辑
今天
1K
14

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部