Java虚拟机运行时数据区域

Java虚拟机将其所管理的内存划分为若干个不同的数据区域。这些区域都有着各自的用途,以及创建和销毁时间。其中有一些会随着虚拟机启动而启动,随着虚拟机退出而销毁;有些则是与线程一一对应,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。划分的几个运行时区域如下:

1.    PC寄存器

Java虚拟机支持多条线程同时执行,每条线程都有自己的PC寄存器(program counter register)。PC寄存器用来指示当前线程所执行字节码指令的地址,说白了就是记录各个线程执行的位置。如果正在执行的是Native方法,PC寄存器的值则为空(undefined)。

2.    Java方法栈

与PC寄存器一样,Java方法栈也是线程私有的。这个栈的生命周期与线程相同,与线程同时创建,线程结束也会随着销毁。Java方法栈用于存储栈帧(Frame,栈帧是方法运行时的基础数据结构,包括局部变量表、操作数栈、动态链接、方法出口等信息)。每一个方法从调用直至执行结束完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。(栈容量设置:-Xss设定)

Java虚拟机规范中,定义了两种异常情况:

(1)如果线程请求分配的栈深度超过Java方法栈允许的最大深度,Java虚拟机将会抛出一个StackOverflowError异常。

(2)如果Java方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的虚拟机栈,那么Java虚拟机将会抛出OutOfMemoryError异常。

3. 本地方法栈

本地方法栈(Native Method Stack)与虚拟机栈的作用类似。虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机执行Native方法服务。与虚拟机栈一样,本地方法栈也会抛出StackOverflowError异常和OutOfMemoryError异常。

4. Java堆

Java虚拟机中,Java堆(Java heap)是被所有线程共享的一块区域,在虚拟机启动时创建。此内存区域的唯一目的是存放类实例对象和数组对象。几乎所有的类实例对象和数组对象都在这里分配内存。是Java虚拟机所管理的内存中最大的一块。(存储对象实例数据)

Java堆可以是固定大小的,也可以是扩展的。当前主流的Java虚拟机都是按照可扩展来实现,通过参数-Xmx和-Xms设置堆的最小值和最大值。

Java堆可能抛出异常的情况:堆中没有足够的内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemeroryError异常。

5. 方法区

与Java堆一样,方法区(method area)也是各个线程共享的区域,在虚拟机启动时创建。主要是用于存储每一个类的结构信息,例如,运行时常量池(runtime constant pool)、字段和方法数据、构造函数和普通方法的字节码内容。还包括一些在类、实例、接口初始化时用到的特殊方法。(存储对象类型数据)。配置方法区大小使用参数:-XX:PermSize和-XX:MaxPermSize。

方法区可能抛出异常的情况:方法区的内存空间不能满足内存分配需求时,Java虚拟机将会抛出一个OutOfMemoryError:PermGenspace的异常。

Java虚拟机加载class文件后,其中Java类会被存储到方法区(Method Area)。实际运行时,虚拟机会执行方法去内的代码。

6. 直接内存

NIO类是基于通道(Channel)与缓冲区(Buffer)方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。NIO操作需要使用到直接内存(Direct Memory)。

直接内存:可通过-XX:MaxDirectMemorySize调整大小。内存不足时抛出OutOfMemoryError或者OutOfMemoryError:Direct buff memory。

6. 运行时常量

运行时常量池(runtime constant pool)是方法区的一部分。在加载类和接口到虚拟机后,就在方法区创建对应的运行时常量池。它是class文件中每一个类或接口的常量池表的运行时表示,它包含了若干种不同的常量。用于存放在编译期间生成的各种字面量个符号引用。

可能抛出异常的情况:在创建类和接口的运行时常量池时,当常量池所需的内存空间超过方法区所能提供的最大值时,抛出OutOfMemoryError异常。

7. 栈帧结构

栈帧存储于Java虚拟机栈中。栈帧是一种数据结构,用于存储方法运行时的数据,包括局部变量表、操作数栈、动态链接、方法出口等信息。每一个栈帧都有自己的局部变量表、操作数栈、和指向当前方法所属的类的运行时常量池的引用。栈帧随着方法调用而创建,随方法结束而销毁。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈、出栈的过程。

7.1 局部变量表

局部变量表是一组变量值存储空间,用于存放实例方法的”this指针”、方法参数以及方法内部定义的局部变量。在Java程序编译为Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的局部变量表的最大容量。

一个局部变量可以保存一个类型为boolean、byte、char、short、int、float、reference、和retuanAddress的数据。两个局部变量可以保存一个类型为long或者double的数据。这么看来,局部变量表等价于一个数组,并且可以用正整数来索引。出了long、double值需要用两个数组单元来存储之外,其他基本类型以及引用类型的值均占用一个数组单元。(javap命令编译出来的class文件,方法里面的局部变量是用槽(slot)来表示的,double两个槽,int一个槽)。

因此,在32位的HotSpot中基本类型将占用4个字节;而在64位的HotSpot中,基本类型将占用8个字节。

参考资料:

【1】 周志明. 深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)【M】.北京:机械工业出版社,2013

【2】爱飞翔,周志明(译).Java虚拟机规范(Java SE 8版)【M】.北京:机械工业出版社,2015.

Java虚拟机学习笔记(一)的更多相关文章

  1. 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回

    <深入Java虚拟机学习笔记>- 第19章 方法的调用与返回

  2. 《深入Java虚拟机学习笔记》- 第16章 控制流

    <深入Java虚拟机学习笔记>- 第16章 控制流

  3. 《深入Java虚拟机学习笔记》- 第17章 异常

    <深入Java虚拟机学习笔记>- 第17章 异常

  4. 《深入Java虚拟机学习笔记》- 第13章 逻辑运算

    <深入Java虚拟机学习笔记>- 第13章 浮点运算

  5. 《深入Java虚拟机学习笔记》- 第14章 浮点运算

    <深入Java虚拟机学习笔记>- 第13章 浮点运算

  6. 《深入Java虚拟机学习笔记》- 第8章 连接模型

    Java虚拟机学习笔记(八)连接模型

  7. 《深入Java虚拟机学习笔记》- 第4章 网络移动性

    Java虚拟机学习笔记(四)网络移动性

  8. 《深入Java虚拟机学习笔记》- 第2章 平台无关

    Java虚拟机学习笔记(二)平台无关

  9. Java虚拟机学习笔记——JVM垃圾回收机制

    Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...

  10. 深入理解java虚拟机学习笔记(一)JVM内存模型

    上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...

随机推荐

  1. TCPDF 背景图片透明度

    1.TCPDF 背景图片透明度  参考:https://bbs.csdn.net/topics/392364981 效果: 2.画一条线: 2.1方法解说  /*画一条线: x1:线条起点x坐标 y1 ...

  2. javabean简介

    Javabean简介 JavaBean是一个可重复使用的软件组件.实际上JavaBean是一种Java类,通过封装属性和方法成为具有某种功能或者处理某个业务的对象,简称bean.由于javabean是 ...

  3. linux 使用sh@d0ws0cks client

    Linux Centos7下安装使用Shadowsocks客户端,实现*** 准备 SS: 搭建一个可以连接外网的服务器 教程可见 自己动手搭梯子 服务器:本人用的腾讯云服务器,系统为Centos7 ...

  4. Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器

    上一篇<更加简练的编程体验>提供了最新版本的Dora.Interception代码的AOP编程体验,接下来我们会这AOP框架的编程模式进行详细介绍,本篇文章着重关注的是拦截器的定义.采用“ ...

  5. [Swift]LeetCode605. 种花问题 | Can Place Flowers

    Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...

  6. [Swift]LeetCode982. 按位与为零的三元组 | Triples with Bitwise AND Equal To Zero

    Given an array of integers A, find the number of triples of indices (i, j, k) such that: 0 <= i & ...

  7. iFace安全专家揭秘:存放在区块链钱包中的比特币,其实已经早就不属于你……

    自MoreToken钱包跑路之后,2019年3月以来陆续多个钱包.交易所跑路,造成了大量用户账户被盗,仅MoreToken钱包用户损失总价值就达12.2亿人民币,用户损失惨重.为什么这么多钱包.交易所 ...

  8. 利用Zabbix来监控Windows Performance Counter

    Windows的性能计数器提供了很多系统的性能指标度量,通过Windows的性能计数器,我们可以对Windows的服务器的当前运行状态有个即时的情况了解. Zabbix Agent支持(Win) pe ...

  9. BBS论坛(三十)

    30.显示评论和添加评论功能完成 (1)apps/models.py class CommentModel(db.Model): __tablename__='comment' id=db.Colum ...

  10. .NET Core WebApi中实现多态数据绑定

    什么是多态数据绑定? 我们都知道在ASP.NET Core WebApi中数据绑定机制(Data Binding)负责绑定请求参数, 通常情况下大部分的数据绑定都能在默认的数据绑定器(Binder)中 ...