Java虚拟机学习笔记(一)
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虚拟机学习笔记(一)的更多相关文章
- 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回
<深入Java虚拟机学习笔记>- 第19章 方法的调用与返回
- 《深入Java虚拟机学习笔记》- 第16章 控制流
<深入Java虚拟机学习笔记>- 第16章 控制流
- 《深入Java虚拟机学习笔记》- 第17章 异常
<深入Java虚拟机学习笔记>- 第17章 异常
- 《深入Java虚拟机学习笔记》- 第13章 逻辑运算
<深入Java虚拟机学习笔记>- 第13章 浮点运算
- 《深入Java虚拟机学习笔记》- 第14章 浮点运算
<深入Java虚拟机学习笔记>- 第13章 浮点运算
- 《深入Java虚拟机学习笔记》- 第8章 连接模型
Java虚拟机学习笔记(八)连接模型
- 《深入Java虚拟机学习笔记》- 第4章 网络移动性
Java虚拟机学习笔记(四)网络移动性
- 《深入Java虚拟机学习笔记》- 第2章 平台无关
Java虚拟机学习笔记(二)平台无关
- Java虚拟机学习笔记——JVM垃圾回收机制
Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...
- 深入理解java虚拟机学习笔记(一)JVM内存模型
上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...
随机推荐
- Luogu P1894 [USACO4.2]The Perfect Stall
传送门 是道绿题???二分图(网络流)不应该是蓝打底??? 这题浏览一遍就知道是二分图(网络流)算法喽,二分图代码太短,不想写(←这人???),所以就拿网络流练练手. 设源点S=0,汇点T=n+m+1 ...
- 企业IT管理员IE11升级指南【13】—— 如何把IEMP迁移到GPP
企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ...
- Trie树详解及其应用
一.知识简介 最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用. 字典树(Trie)可以保存一些字符串->值的对 ...
- [Swift]LeetCode211. 添加与搜索单词 - 数据结构设计 | Add and Search Word - Data structure design
Design a data structure that supports the following two operations: void addWord(word) bool search(w ...
- [Swift]LeetCode342. 4的幂 | Power of Four
Given an integer (signed 32 bits), write a function to check whether it is a power of 4. Example 1: ...
- [Swift]LeetCode860. 柠檬水找零 | Lemonade Change
At a lemonade stand, each lemonade costs $5. Customers are standing in a queue to buy from you, and ...
- [Swift]LeetCode944. 删除列以使之有序 | Delete Columns to Make Sorted
We are given an array A of N lowercase letter strings, all of the same length. Now, we may choose an ...
- 第一次写html网页
步骤一:(在notpad中写) <html> <head> <title>登录页面</title> </head> <body> ...
- Linux 设置自启动服务
0 为停机,机器关闭.(千万不要把initdefault设置为0 ) 1 为单用户模式,就像Win9x下的安全模式类似. 2 为多用户模式,但是没有NFS支持. 3 为完整的多用户 ...
- BBS论坛(十八)
18.首页轮播图实现 (1)front/css/front_base.css .main-container{ width: 990px; margin: 0 auto; overflow: hidd ...