文档章节

JVM学习总结(一)运行时数据区

hensemlee
 hensemlee
发布于 04/22 11:46
字数 1556
阅读 86
收藏 25

《深入Java虚拟机》这本书买了有一段时间了,当时看的时候就只是看,并没有边看边总结啥的,最后发现到脑子里面的根本所剩无几了。现在开始要好好归纳总结地再学习一遍。

运行时数据区域

JVM在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。所管理的内存包括以下几个运行时数据区域

输入图片说明

  1. 程序计数器
  • 作用:记录当前线程所执行的字节码的行号。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
  • 意义:JVM的多线程是通过线程轮流切换并分配CPU时间方式来实现的,因此,为了线程切换后能恢复到正确的指定位置,每条线程丢都需要一个独立的程序计数器
  • 存储内容 : 若线程正执行的是一个Java方法时,程序计数器中记录的是正在执行的线程的虚拟机字节码指令的地址 若线程正执行的是一个本地方法时,程序计数器中的值为空
  • 可能发生的异常: 程序计数器是唯一一个Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域
  1. Java虚拟机栈
  • 作用:描述Java方法执行的内存模型,每个方法执行的时候都会创建一个栈帧,栈帧里面存储了局部变量表、操作数栈、动态链接、方法出口等信息
  • 意义:方法从开始执行到执行结束,就对应着一个栈帧在Java虚拟机栈中入栈到出栈的过程
  • 存储内容: 局部变量表(编译期间可知的各种基本数据类型、引用类型和指向一条字节码指令的returnAddress类型)、操作数栈、动态链接、方法出口等信息 值得注意的是:局部变量表所需的内存空间在编译期间完成分配。在方法运行的阶段是不会改变局部变量表的大小的
  • 可能发生的异常: StackOverflowError异常:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出该异常 OutOfMemoryError异常:如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可以动态扩展,只不过虚拟机规范中也允许固定长度的虚拟机栈)如果扩展时无法申请到足够的内存,就会抛出该异常
  1. 本地方法栈
  • 作用:为JVM所调用到的Native即本地方法服务 ps:Sun HotSpot虚拟机 直接把本地方法栈和虚拟机栈合二为一
  • 可能发生的异常:同虚拟机栈,存在StackOverflowError异常和OutOfMemoryError异常
  1. Java堆
  • 作用:分配所有的对象实例以及数组,但随着即时编译(JIT)器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术使得对象都在对上分配变得不那么绝对
  • 意义:Java堆是Java虚拟机所管理的内存中最大的一块,被所有线程共享,在JVM启动时创建。Java堆是垃圾收集器管理的主要区域,Java堆可以细分为:新生代(Young Generation)、老年代(Old Generation)、永久代(Permanent Generation);新生代再细致一点可以分为Eden空间、From Survivor空间、To Survivor空间。如果配置-XX:+/-UseTLAB,每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)
  • 存储内容: 存放对象实例及数组(创建数组时,创建动作由字节码指令newarray触发,虚拟机自动生成一个为java.lang.Object的子类的类,这个类中实现了数组中应有的属性和方法,可以直接访问的为public类型的length属性和clone()方法),几乎所有的对象实例都在这里进行分配。堆可以处于物理上不连续的内存空间,只要逻辑上是连续的就可以
  • 可能发生的异常:如果堆中没有内存完成实例分配,并且堆也无法再拓展(堆可以是固定大小的,拓展可通过-Xms和-Xmx参数控制)时,将会抛出OutOfMemoryError异常
  1. 方法区
  • 作用:用于存储运行时常量池、已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
  • 意义:对运行时常量池、常量、静态变量等数据做出了规定
  • 存储内容:运行时常量池(具有动态性)、已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
  • 可能发生的异常:当方法区无法满足内存分配需求的时候抛出OutOfMemoryError异常

运行时常量池

运行时常量池是方法区的一部分。Class文件中出了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期间生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放

jdk6、jdk7、jdk8对于方法区的设计不同

  • 运行时常量池在JDK1.6及之前版本的JVM中是方法区的一部分,而在HotSpot虚拟机中方法区放在了”永久代”。所以运行时常量池也是在永久代的
  • 但是JDK1.7及之后版本的JVM已经将运行时常量池从方法区中移了出来,在Java 堆(Heap)中开辟了一块区域存放运行时常量池
  • 而在JDK1.8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间

© 著作权归作者所有

共有 人打赏支持
hensemlee
粉丝 8
博文 64
码字总数 42691
作品 0
徐汇
程序员
JVM 运行时数据区简介及堆与栈的区别

理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机制,...

大数据之路
2015/08/02
0
1
001. 深入JVM学习—Java运行流程

Java运行流程图 2. Java运行时数据区 3. Java虚拟机栈 栈内存是线程私有的,其生命周期和线程相同; 虚拟机栈描述的是Java方法执行的内存模型:执行一个方法时会产生一个栈帧随后将其保存到栈...

影狼
06/22
0
0
Java虚拟机基础——2JVM运行时数据区

Java虚拟机整体篇幅如下: Java虚拟机基础——1Java的内存模型 Java虚拟机基础——2JVM运行时数据区 Java虚拟机基础——3类加载机制 Java虚拟机基础——4内存回收机制 本篇文章主要讲解JVM运...

隔壁老李头
10/03
0
0
面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb
05/12
0
0
Java虚拟机运行时数据区结构

本文部分参考自《Java虚拟机规范(Java SE 7版)》的中译本和周志明的《深入理解Java虚拟机》,另加个人理解。原书对Java虚拟机运行时数据区描述只有6页,同时参考其他网络网资料,个人能力所...

foodon
2014/12/09
0
4

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部