JVM运行时数据区域

运行时区域包括: 

        方法区(Method), 堆(Heap), 程序计数器(Program Counter Register), 虚拟机栈(Java Virtual Machine Stack)和本地方法栈(Native Method Stack)五部分, 如图 : 

Java虚拟机运行时数据区域划分

1.  程序计数器(Program Counter Register)

1.2 程序是很小的内存空间, 可以看做线程执行字节码的行号指示器 .

1.2  字节码解释器工作时就是通过改变这个计数器的值来选择下一条要执行的字节码指令 , 分支,循环,跳转,异常处理,线程恢复等基础功能都依赖计数器来完成.

1.2 程序计数器的区域私有原因 : Java的多线程是通过线程轮流切换和控制执行时间来实现的. 在任何时刻,一个处理器(多核表示一个核) 只执行一个线程.为保证线程在切换之后,能恢复到正确的位置,则每条线程都需要一个程序计数器. 各个线程的计数器互不干干涉,独立保存.

1.2 程序计数器的记录内容: Java方法 记录的是正在虚拟机执行的字节码的指令地址 , Native方法, 记录的值为空(undefined).

1.2 异常 : Java虚拟机规范中,没有规定任何的 OutOfMemoryError 情况的区域.

2. Java虚拟机栈(Java Virtual Machine Stacks)

2.1 线程私有 , 生命周期与线程相同.

2.2 虚拟机栈是用来描述Java方法的执行内存:

    2.2.1 每个方法在执行的同时会创建一个栈帧;

    2.2.2 用来存储局部变量表 , 操作数栈,动态链接和方法出口等信息;

    2.2.3 每一个方法的调用直至执行完成, 都对应着一个栈帧在虚拟机中的入栈和出栈过程;

    2.2.4 局部变量表中存储着八种基本类型(byte,short,int,long,float,double,boolean,char),引用类型,returnAddress类型(指向了一条字节码指令的地址);

    2.2.5 64位长度的long和double类型,会占用2个局部变量空间,其余类型1个; 局部变量表所需的内存在编译期间就分配完成, 所以空间是完全确定的,运行时间不会改变局部变量的表的大小.

2.3 异常

    2.3.1 StackOverFlowError异常, 线程请求的栈深度大于虚拟机所允许的深度时抛出异常. 常见情况  , 无限递归调用

    2.3.2 OutOfMemoryError 异常, 大部分情况下虚拟机的栈都是可自动扩容的,如果扩展时无法申请到足够的内容就会抛出异常;

3. 本地方法栈(Native Method Stack)

3.1 与Java虚拟机栈功能相似 , 区别在于Java虚拟机执行的Java方法 , 本地方法栈执行的是Native方法服务.

3.2 Java虚拟机规范中, 对本地方法使用的 语言, 使用方式和数据结构都没有强制规定, 可以自由实现

3.3 Sun Hotspot 虚拟机直接把本地方法和 虚拟机站方法合并 .

3.4 会抛出 StackOverFlowError 和 OutOfMemoryError 异常, 同虚拟机栈

4. 堆(Java Heap)

4.1 是Java虚拟机中内存最大的一块, 被线程共享,在虚拟机启动时被创建.

4.2 几乎存放所有实例对象. 因为 JIT编译器的发展和逃逸分析技术成熟 , 栈上分配,标量替换技术, 将绝对变得不绝对.

4.3 Java堆 是垃圾管理等的主要区域, 又称GC堆. 

4.4 现在收集器都是采用 分代收集算发 , 将Java细分为 : 新生代和老年代 , 在细分为 Eden空间, From Survivor 空间 , To Survivor空间

4.5 Java堆可以处于物理上不连续的内存空间, 只要逻辑上连续即可

4.6 当前主流虚拟机基本都是可扩展的 , 扩展通过(-Xmx 和 -Xms控制)

4.7 异常 OutOfMemoryError : 在堆中没有完成实例的分配, 堆也无法完成在扩展.

5. 方法区(Method Area)

5.1 是线程共享的区域.

5.2 存储内容: 被虚拟机加载的类信息 ,常量 , 静态变量, 即时编译后的代码等数据.

5.3 方法区 != 永久代 , Hotspot虚拟机的实际团队, 把GC分代收集扩展至方法区,或者是 使用永久代来实现方法区. 这样Hotspot 的垃圾收集器可以和堆一样来管理这部分内存 ,能省去专门为方法区编写内存管理的内容.

5.4 用永久代来实现方法区的问题 : 

    5.4.1 永久代有 -XX:MaxPermSize的上限, 容易遇到内存溢出的问题;

    5.4.2 极少数方法(String.intern()) 会因为这个原因在不同的虚拟机下有不同的表现;

5.5 JDK 1.7 的Hotspot中,已经把原本放在永久代的 字符串常量池 移出.

5.6 方法区的垃圾回收 : 并非垃圾进入了永久代就是 永久存在了 , 这区域的垃圾回收主要针对 常量池和类型的卸载.

5.7 但是这区域的回收能力低 , 尤其类型的卸载, 条件相当苛刻  

5.8 异常 OutOfMemoryError , 方法区没法满足内存分配需求时 抛出.

6. 运行时常量池(Runtime Constant Pool)

6.1 是方法区的一部分 , Class文件中包含内容有, 类的版本信息,字段,方法,接口等描述信息 , 还有一项信息是常量池.

6.2 用于存放编译时期生成的各种字面量和符号引用, 在类被加载进方法区的时候存入常量池.

6.3 动态性, Java语言中并不要求常量一定在编译器才产生, 运行时期也能将新的常量放入池中 , 利用的较多的就就是String类的intern 方法.

6.4 异常 OutOfMemoryError : 常量池中无法再申请到内存时抛出.

7. 直接内存(Direct Memory)

7.1 并不是虚拟机的运行时数据区的一部分,也不是Java虚拟机规范定义的内存区域.

7.2 NIO(New Input/Output) , 引入一种基于管道(Channel)与缓冲区(buffer)的I/O方式, 可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作.

7.3 分配内存不会影响Java堆大小的限制, 但是受本机总内存大小和处理器寻址空间限制.

7.5 异常 OutOfMemoryError 配置虚拟机参数时 , 会根据实际内存设置 -XMx等参数新消息, 忽略直接内存, 使各个内存区域总和大于物理内存限制 , 然后抛出异常.

8. 总结(Summary)

8.1 有内存划分, 每个内存的用处

8.2 内存溢出异常(OutOfMemoryError)

    8.2.1 虚拟机的栈都是可自动扩容的,如果扩展时无法申请到足够的内容就会抛出异常;(同本地方法栈)

    8.2.2 堆中没有完成实例的分配, 堆也无法完成在扩展

    8.2.3 方法区没法满足内存分配需求

    8.2.4 常量池中无法再申请到内存

    8.2.5 忽略直接内存, 使各个内存区域总和大于物理内存限制

8.3 堆得扩展通过 -Xmx 和 -Xms控制

8.4 永久代有 -XX:MaxPermSize限制

注: 内容基本来源于 <<深入理解Java虚拟机>>  第2版  周志明著

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

推荐阅读更多精彩内容