JVM系列之内存结构运行时数据区

布朗大学(美国)校训:“我们信赖上帝。”


转眼已进入深秋,在书房里听听歌写写文章,蛮舒服惬意的事情!

继续聊jvm系列,上两节聊了class文件结构和类加载机制,接下来聊聊面试的高频点,jvm的内存结构模型,及实战中对运行时数据区的理解,闲话不多说,先来一张图吧,请阅:
内存结构规范.png
这张图基本把前面讲的也一起串起来了,先是静态编译把源码编译成class字节码文件,再通过加载器加载进内存,接下来就进入了运行时数据区域了,这块即是jvm内存结构规范,把此区域划分为堆/方法区/栈区(本地方法栈/虚拟机栈/程序计数器),其中栈区为线程私有,堆和方法区为线程共享。接下来就重点讲解下这几个区域:

一 Java堆(Heap)

这个大家估计耳熟能详,随口便说是放置new对象的地方,没错,主要是存储对象实例,几乎所有的对象实例都在这个区域分配内存。看到这里估计有朋友问了,那是不是有的对象实例不是在堆上分配的,jvm还真提供了,是否听说过栈上分配和TLAB,栈上分配是为了减少gc的压力,因为随栈弹出而释放并不会出发gc,TLAB则是优化对象实例在堆中并发分配的效率,具体详细可自行百度了解,这里放一张对象分配图,摘自实战Java虚拟机一书中:
对象分配.png

堆是jvm管理内存最大的一块,是线程共享的一块区域,在jvm启动时创建;可能有些同学经常遇到OOM(OutOfMemoryError)异常,这里考大家一题,如何模拟OOM?
很简单,首先设置下jvm参数(-Xms 1m -Xmx 2m),然后在main函数初始化一个大的数组即可浮现。

二 方法区(Method Area)

与堆一样,也是被线程共享的区域,同样会出现OOM(OutOfMemoryError)异常,此区域主要存储如下信息:
1/已被虚拟机加载的类信息,即元数据;
2/静态变量和常量,这里维护一个运行时常量池;
3/JIT(即时编译)后的代码,这个上节有提到过;
这里,分享一个常考的面试题:

/**
     * @author 阿伦故事
     * @Description:
     *  小试牛刀
     * */
    public static void main(String[] args) {
        String s = "1"+"2"+"3";// 1 这里创建了几个对象?
         
        String s1 = "allen story";// 2 
        String s2 = new String("allen story");// 3 这里创建了几个对象?
    }
    /**
     * 分析如下:
     * 1处只创建了一个对象,即“123”在运行时常量池,栈中引用s直接指向常量池
     * 3处也只创建一个对象,即在堆中new了一个对象实例,“allen story”在2处已
     * 经在运行时创建,堆中对象直接存储该指向即可。
     * */

三 程序计数器(Program Counter Register)

了解jvm内存结构规范的朋友们,肯定脱口而出,pc用于记录所属线程所执行的字节码的执行行号,没错,有多少朋友理解这个意思?如果了解寄存器的话,那就容易很多,cpu执行的指令就是从指令寄存器取的,而pc就是用于存储下一条指令的偏移地址。当然,pc是线程私有的,存储的自然所属线程的指令地址。
唯一一个在JVM规范中没有规定任何OutOfMemoryError的区域。
如何理解?
很简单,pc只存储下一条指令的地址,并不会随着指令量级的增长而增长。

四 栈(Stack)

栈分为本地方法栈和虚拟机栈,顾名思义,一个是用于native方法的,栈的特性是先进后出,这也是递归调用的逻辑。栈是线程私有的,每启动一个新线程时,jvm都会为它分配一个Java栈,以栈帧为单位保存线程的运行状态。
虚拟机只会对Java栈执行两种操作:以栈帧为单位的入栈或者出栈。
这里也容易出现一个异常,StackOverflowError,如何模拟?
理解了就很容易,超过了栈深度不就异常了嘛?
只需要写个递归调用,无返回不退出,一直调用无退出条件,那不就一直在入栈而不弹栈,那不栈溢出了嘛?另可通过测试得知jvm为每个线程分配的内存默认是1M,具体可测试下,即jvm参数(-Xss 1m)。
栈在jvm内存结构中非常重要,我们有必要详细了解它的组成部分,由基本类型变量区、执行环境上下文、操作指令区(存放操作指令)组成,只是保存基本类型数据和自定义对象的引用,即堆中实例对象的地址或偏移地址。

五 小结

介绍了jvm内存结构划分,稍稍总结下重点区域,堆/方法区/栈之间的关系(如图),以一个例子串下类的加载/分配与执行。


内存结构关系.png

Sample:

/**
     * @author 阿伦故事
     * @Description:
     *  jvm执行流程
     * */
    public static void main(String[] args) {
        Person person = new Person();
         person.sayHello();
    }
    /**
     * 流程如下:
     * 上述很简单,就是main主线程创建一个person对象实例,调用其sayHello方法
     * 1/先去方法区寻找Person类的元数据信息;
     * 2/如果找不到,Classloader加载Person类信息存储内存方法区;
     * 3/在堆中创建Person对象,并持有方法区中Person的元信息的引用;
     * 4/把引用变量person添加到栈中,指向堆中的内存对象Person实例;
     * 5/执行person.sayHello()时,JVM根据person定位到堆空间的Person实例;
     * 6/根据Person实例持有的方法区引用,获取Person元信息与sayHello方法执行字节码。
     * */
执行流程.png

特此声明:
分享文章有完整的知识架构图,将从以下几个方面系统展开:
1 基础(Linux/Spring boot/并发)
2 性能调优(jvm/tomcat/mysql)
3 高并发分布式
4 微服务体系
如果您觉得文章不错,请关注阿伦故事,您的支持是我坚持的莫大动力,在此受小弟一拜!

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

推荐阅读更多精彩内容