JVM 内存区域与GC

本文思路
1.JVM运行时内存划分
2.对象创建内存动作
3.Java线程栈
4.JVM垃圾收集器

1.JVM运行时内存划分

1.1 程序计数器

当前线程所执行的字节码的行号指示器。字节码解释器工作的时候就是通过改变这个计数值来选取下一条要执行的字节码指令。

1.2 虚拟机栈(java方法栈)

线程私有,java方法执行时的内存模型,每个方法执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、方法出口等信息

局部变量表其实就是一个方法内的局部变量对应的指针。

1.3 本地方法栈

Native 方法执行的线程栈

1.4 方法区

线程共享区域,存储已经被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据。

运行时常量池
方法区的一块,保存Class文件中描述的符号引用,也会把翻译出来的直接引用也存储在这里。它的主要特征是具备动态性,编译器和运行时的常量都可以进入,比如的string 字符串常量池 intern()方法,就是利用的该特性。

1.5 堆

JVM里所管理的内存中最大的一块,线程共享,存放所有对象实例。GC也是针对该区进行回收。

2.对象创建内存动作

我们new一个对象的时候,都发生了什么?

2.1 jvm看到new指令,判断指令参数是否能在常量池中定位到这个类的符号引用(可以认为我们的类名),检查这个符号引用代表的类是否已被加载、解析和初始化过,没有的话需要进行class加载。

2.2 jvm从堆里分配内存

2.3 分配的内存空间都初始化为零,保证对象的实例字段再Java代码中不赋初始值就能直接使用。

2.4 jvm对对象做一些设置。设置存放在对象头,对象头里主要包含一些hashcode、GC、元数据、锁等。

2.5 执行init方法。此刻对于JVM一个对象已经创建完毕,接下来会按照程序员的一样做一些初始化动作。

new 对象流程示意图

3.Java线程栈

每执行一个方法,jvm都会为此创建一个栈帧,我们的一条调用链路,有一个一个的栈帧组成,最后形成一个线程栈,当栈的长度过长或者超过内存大小就好报栈溢出的异常。

基本数据类型,string这些的指针指向的是常量池。而实例对象也就统称为reference类型,指向的是一个对象的引用,访问堆中的对象具体位置有两种方式,通过句柄池进行句柄访问,另一种直接通过指针。

3.1 句柄方式

java堆中会划分一块内存用来作为句柄池,reference存储的就是句柄地址,而句柄包含了实例数据和类型数据各自的具体地址。具有稳定的句柄地址的优势,当对象移动,只会更改句柄中的实例数据指针。

3.2 直接指针访问

reference存储的直接就是对象地址,速度快,节省了一次指针定位的开销。java中对象的访问特别多,所以在java中该方式使用的最多。

4.JVM垃圾收集器

栈,程序计数器这些随线程而生,随线程而忘。而Java堆和方法区则是在运行期间才知道会创建哪些对象,需要多少内存。垃圾回收器所关注的则是这部分内存。

如何判断对象对象已死?
目前主流实现主要基于可达性分析来判定对象存活。大概思路就是通过GC ROOT 对象向下分析,不在链路上的对象则认为是已死对象。

灰色表示可回收对象

哪些对象可以作为GC ROOT对象?

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区常量引用的对象
  • 本地方法栈中引用的对象

安全区域
JVM可以通过GC ROOT快速定位到要回收的对象,但是程序是在运行中的,对象的关系也会发生变化。JVM只有当程序进入安全点时,然后暂停程序进行回收。

安全点的选定是以程序是否具有长时间执行的特征为标准进行选定。“长时间执行”最明显的特征就是指令序列复用(一组),如方法跳转、循环跳转、异常跳转等,具备这些功能的指令才会产生safePoint。

在GC发生时,一般会采用主动式中断,jvm在要发生GC时不会干预线程,会设置一个标志,所有的线程主动去轮询,当执行线程发现了这个标识就自己中断挂起。

回收算法
标记清除
步骤:将内存中需要回收的对象打上标记,然后回收打上标记的对象。
缺点:会产生内存碎片

复制
步骤:将内存一分为2,需要回收的时候,将存活对象copy到另一个内存区域,然后原来的内存区域就只剩下待回收的对象,直接全部清除
缺点:可使用内存只有一半,代价太大

标记整理
标记清除类似,多了一个整理的过程,在清除后,会让存活的对象向一个方向移动,最后达到内存连续,解决碎片问题。

收集器

JVM采用分代垃圾回收。在JVM的内存空间中把堆空间分为年老代和年轻代。将大量(据说是90%以上)创建了没多久就会消亡的对象存储在年轻代,而年老代中存放生命周期长久的实例对象。年轻代中又被分为Eden区(圣经中的伊甸园)、和两个Survivor区。新的对象分配是首先放在Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到年老区。

按代回收

JVM提供了很多个收集器,目前主要有Serial,Serial Old,ParNew, Paralle Scavenge,Paralle Scavenge Old,CMS,G1。当前用的最多的是 CMS和G1。
SerialSerial Old
单线程,简单高效。进行GC的时候会把所有工作线程停掉,是早期的回收期。serial old是专门回收老年代的。

ParNew
Serial的并发版本

Paralle ScavengeParalle Scavenge Old
采用复制算法,追求吞吐量,可以高效的利用CPU时间,尽快完成程序的运算任务,适合在后台运算而不需要太多交互的程序。

吞吐量 = \frac{运行用户代码时间}{运行用户代码时间 + 垃圾收集时间} \quad

CMS
是一种以获取最短回收停顿时间为目标的收集器。对于尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验的系统很适合。

采用标记清除算法,所以缺点就是会有大量的空间碎片。

G1
暂时看的不是特别清楚,可以参考下
https://www.cnblogs.com/ASPNET2008/p/6496481.html
https://mp.weixin.qq.com/s/ZwlT89vsvD2e0qEuxZto3Q
自行理解。

--
参考文章
http://www.idouba.net/a-simple-example-demo-jvm-allocation-and-gc/
http://gityuan.com/2016/01/09/java-memory/
https://blog.csdn.net/top_code/article/details/51288529

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容