【jvm】jvm运行时数据区

java虚拟机在运行时会将内存空间划分为不同的数据区域。每个区域都有各自的用途以及生命周期。有些区域伴随着JVM进程的存在而存在,有些区域“随线程而生,随线程而死”。

JVM运行时数据区

jvm运行时数据区图示

程序计数器

作用:当前线程所执行的字节码的行号指示器,字节码解释器在工作时通过改变计数器的值来选取下一条需要执行的字节码指令。
特点
1、线程私有,JVM多线程是通过轮流切换并分配CPU时间的,在任何一个时刻,一个CPU(一个核)只会执行一条线程中的指令。为了保证每条线程切换后恢复到正确的位置,每个线程都需要一个独立的程序计数器。
2、如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的时native方法,则计数器的值为空。
3、此内存区域是唯一一个没有规定任何OOM情况的区域。

虚拟机栈

虚拟栈描述的是java方法执行时的内存模型(JMM),每个方法在执行的时候会创建一个栈帧(stack frame),栈帧的数据结构包括局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从开始执行到退出的过程,及对应着栈帧在虚拟机栈中入栈到出栈的过程。(关于栈帧及方法执行的具体细节,在执行子系统中会有具体描述)
虚拟机栈可能出现的异常状况:
stackOverFlow:栈溢出,如果方法调用的栈深度大于虚拟机允许的最大栈深度,就会出现stackOverFlow异常。递归方法调用时,如果调用栈过深,就有可能引发栈溢出。这也是为什么慎用递归的原因之一以及编写递归时的注意点。
OutOfMemory:如果虚拟机栈允许动态扩展,在扩展时无法申请到足够的内存,就会抛出OOM异常。

本地方法栈

与虚拟机栈作用类似,区别是虚拟机栈为执行字节码服务,而本地方法栈为虚拟机使用到的native方法服务。由于虚拟机规范中没有对本地方法栈中使用的语言、数据结构做出强制规定,具体的虚拟机可以自由实现。Sun HotSpot虚拟机直接把虚拟机栈和本地方法栈合二为一。本地方法栈也会抛出stackOverFlow和OOM异常。

java堆

java堆是java虚拟机管理的最大一块内存,被线程共享。虚拟机垃圾收集器的主要区域。
作用:几乎所有的对象内存空间都在堆上分配。
特点
1、从内存回收的角度看,由于现在的垃圾收集器基本采用分代回收,java堆还可以细分为老年代和新生代,新生代又可以分为eden、FromSurvivor和ToSurvivor。
(图示所说的永久代,在hotspot虚拟机中就是方法区。但两者并不等价,只是HotSpot将gc分代收集扩展至方法区,或者说用永久代来实现方法区)

java堆的分区

2、从内存分配角度看,线程共享的java堆中可能划分出多个线程共有的缓冲区(Thread Local Allocation Buffer,TLAB)。
无论从哪个角度看,java堆都是存储的对象实例,进一步划分都是为了更好的分配和回收内存。

方法区

方法区和java堆一样,也是线程共享的区域。
作用:存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
特点:同java堆一样不需要连续的内存和可以选择固定大小或者可扩展;可以选择不实现垃圾收集;相对而言,方法区的垃圾收集比较少见,但是并不保证“永久”存在。方法区的垃圾回收目标主要是针对常量池的回收和对类型的卸载(相对类加载而言)。

运行时常量池

方法区的一部分。.class文件中除了类信息外,还有一项就是常量池,用于存放编译器形成的各种字面量和符号引用,这部分内容将在类加载后进入运行时常量池中存放。java虚拟机对class文件格式有着严格的规范要求,只有符合规范的class文件才能被虚拟机装载和执行,但对于运行时常量池,java虚拟机规范没有做任何要求,不同实现的虚拟机可以自己实现这个内存区域。
运行时常量池相对于class文件常量池的另一个特征就是具备动态性,运行期间也可以将新的常量置于池中,并非一定是class文件中的常量。比如String类的intern方法,
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

JVM内存分配策略

java的自动内存管理最终解决了两个问题:给对象分配内存和回收分配的内存。在具体分析内存分配策略之前,我们需要了解对象的内存布局。

对象的内存布局

Jvm 规范并没有规定对象的存储方式,以下都是以hotSpot虚拟机为例
对象在内存中的存储的布局可以分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)

对象头

对象头包括两部分信息:
第一部分为Mark Word,用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据在32位和64位虚拟机(未开启指针压缩)分别为32bit和64bit,Mark Word是一个非固定长度的数据结构,可以根据对象的状态复用自己的存储空间。
另一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。如果对象是一个数组,那么对象头中还必须有一块用于记录数组长度的数据。

实例数据

对象真正存储的有效信息,也是程序代码中定义的各种类型的字段内容。无论是从父类继承的还是子类定义的,都需要记录起来。这部分的存储顺序会受到虚拟机分配策略参数和字段在java源码中定义顺序的影响。

对齐填充

这部分不是必须的,仅仅是为了满足jvm的字节对齐要求

JAVA的内存分配与回收策略

对象优先分配在Eden区。

大多数情况下,对象在新生代Eden区分配,Eden区空间不足时,虚拟机将发起一次MinorGC。

大对象直接进入老年代。

大对象对虚拟机内存分配来说是个坏消息,因为在内存空间还有较多剩余时,为了放置大对象,会提前触发GC。如果大量产生“短命”大对象会引起频繁GC。为此虚拟机提供了一个-XX:PretenureSizeThresHold参数,使得大于这个值的对象直接进入老年代,这样做的目的是避免Eden区及两个Survivor区之间发生大量的内存复制(Eden区采用标记-复制算法进行GC)。

长期存活的对象将进入老年代。

虚拟机为每个对象都定义了一个对象年龄计数器,如果对象在Eden出生并且在第一次MinorGC中存活下来,就将年龄计数器+1,对象每熬过一次GC,年龄就增加1,当年龄增加到一个阈值,就会被分配到老年代。

动态年龄判定。

虚拟机也并不是一定要求必须要达到年龄阈值才将对象放置于老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,那么年龄大于或等于该年龄的对象就可以直接进入老年代。

空间分配担保。

新生代采用复制收集算法来进行GC,为了内存利用率,只保留一个Survivor空间作为轮换备份,因此当minorGC后仍然有大量对象存活的话,就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代。

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

推荐阅读更多精彩内容