Java虚拟机内存结构

Java虚拟机内存结构

1、内存结构图:


程序计数器:当前线程所执行的字节码行号指示器;分支、循环、跳转等控制;当执行的是java方法时是正在执行的虚拟机字节码指令的地址;当执行的是Native(JNI)方法时该指针为空;没有(out of memory error)OMM

栈:生命周期与线程相同,每个方法执行时都会创建一个栈帧(stack frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;每个方法从调用到执行成的过程对应栈帧在栈中入栈到出栈的过程;栈深过大:StackOverFlowError;内存不足:OOM

本地方法栈:Native method stack,跟栈一样,栈服务于java方法,本地方法栈服务于native 方法(JNI),部分虚拟机是合并的。

堆:所以线程共享,存放对象实例,垃圾回收的主要区域,物理内存上可以不连续,会有OOM问题

方法区:线程共享,用于存储已经被虚拟机加载的类信息,常量、静态变量等。类的加载、卸载、常量池回收均发生在此,内存不足会有OOM ; 运行时常量池:方法区一部分,存放编译时期生成的各种字面量和符号引用,具有动态特性,内存不足也会OOM

直接内存:与JVM定义内存区域无关,不归JVM管理,内存不足也会OOM,native库直接分配的堆外内存;不会回收。例如Netty缓冲区,不需要回收,可以反复用

Ps:方法区在1.8称为元空间

永久带替换为元空间的原因:

1、Java7及以前版本的Hotspot中方法区位于永久代中。同时,永久代和堆是相互隔离的,但它们使用的物理内存是连续的。永久代的垃圾收集是和老年代捆绑在一起的,因此无论谁满了,都会触发永久代和老年代的垃圾收集。

2、元空间存在于本地内存,意味着只要本地内存足够,它不会出现像永久代中“java.lang.OutOfMemoryError: PermGen space”这种错误。看上图中的方法区,是不是“膨胀”了。默认情况下元空间是可以无限使用本地内存的,但为了不让它如此膨胀,JVM同样提供了参数来限制它使用的使用。

-XX:MetaspaceSize,class metadata的初始空间配额,以bytes为单位,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当的降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize(如果设置了的话),适当的提高该值。

-XX:MaxMetaspaceSize,可以为metadata分配的最大空间,默认是没有限制的。

-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比。

-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比。

3、思考一下,为什么使用元空间替换永久代?

    表面上看是为了避免OOM异常。因为通常使用PermSize和MaxPermSize设置永久代的大小就决定了永久代的上限,但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。当使用元空间时,可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制。

    更深层的原因还是要合并HotSpot和JRockit的代码,JRockit从来没有所谓的永久代,也不需要开发运维人员设置永久代的大小,但是运行良好。同时也不用担心运行性能问题了,在覆盖到的测试中, 程序启动和运行速度降低不超过1%,但是这点性能损失换来了更大的安全保障。

2、JOL对象的内存布局:

Java Object Layout 对象的内存布局:即对象在内存中如何分布的


数组对象:markword(8)+classPointer(4)+数组长度(4)+实例数据+对齐

Ps:压缩指针和压缩普通对象指针:

使用java -XX:+PrintCommandLineFlags -version命令可以看到包含以下信息:

显示:-XX:+UseCompressedClassPointers -XX:+UseCompressedOops,

其中-XX:+UseCompressedClassPointers是使用压缩类指针,原先是8字节,由于8字节=8x8=64位,2^64位寻址空间太大,因此没必要使用8字节,因此使用了压缩成4字节的压缩指针,4字节的寻址能力:4*8=32位,2^32=4G(2^10=1024=1KB 2^20=1M 2^30=1G)  又由于JVM是8字节一寻址,也就是每8字节作为一个单位,因此实际寻址能力4G*8=32G,ZGC号称最大能够使用4T的内存,ZGC使用8字节作为ClassPointer 其中有42位为类指针,4位为颜色指针,剩余的不知道,2^42=4T。

其中-XX:+UseCompressedOops是表示使用压缩对象指针进行寻址,两个指令应该是一对的。

关闭压缩指针-XX:-UseCompressedClassPointers -XX:-UseCompressedOops指令。使用-即可。

3、对象的创建:

(参考:Java类加载机制和对象创建过程)

虚拟机见到new指令,检查类是否被加载、解析、初始化等。

4、为新对象分配内存的方式:

内存规整:直接移动指针到未被使用的区域(指针碰撞),需要带压缩的GC:Serial、ParNew等带compact的垃圾回收器

内存不规整:空闲列表维护可用空间,例如:CMS等基于mark-sweep的垃圾回收器

5、内存分配的线程安全:

CAS保证,每个线程在jvm预先分配了内存,称为本地线程分配缓冲区TLAB,并同步锁定。

6、TLAB(Thread Local Allocation Buffer):

TLAB(Thread Local Allocation Buffer)线程本地分配缓冲区;JVM分配对象是优先分配到线程栈上,栈上分配不了的(如对象较大)则直接分配在Old区;如果对象不大,优先分配在栈上的TLAB上;TLAB是在Eden区的专门的内存空间,为了防止在Eden区分配空间的多线程竞争资源,JVM为每个线程在Eden区上分配的专属内存空间即TLAB。

7、堆内存逻辑分区:

8、对象的访问定位:

栈上的reference数据操作具体堆上的对象有句柄和直接指针两种方式;

句柄方式:jvm堆上划分内存来作为句柄池,引用时引用存储对象的句柄地址,句柄中包含对象实例数据和类型数据的各自具体地址信息;优点:引用不用修改,比较稳定,对象移动如垃圾回收只要改变句柄值即可;


直接指针:引用直接引用对象地址,对象中包含类型数据指针,指向方法区class;特点:速度快


9、对象的创建过程:

new 指令,开辟空间(申请、初始化),这里的初始化是半初始化,还是默认值,例如对象中有变量 int i=8; 此时初始化后i=0 即默认值,所以称为半初始化

invokespecial ,构造方法,赋值(真正的初始化,i=8)

astore, 对象建立关联,栈空间与堆空间建立关联

初次访问对象

其中2、3两部会发生指令重排

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