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遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...
随机推荐
- unity网络----简单基础
网络 TCP:与打电话类似,通知服务到位 UDP:与发短信类似,消息发出即可 IP和端口号是网络两大重要成员 端口号(Port)分为知名端口号[0-1024,不开放)和动态端口号[1024,10000 ...
- json格式 (JavaScipt Object Notation)
json格式 json语法规则: 01.对象表现形式 key:value 键值对 02.如果有多个数据,之间使用逗号隔开 k1:v1,k2:v2 03.把对象写在大括号中 var student={a ...
- 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
摘要: 主要针对Dao层的一些数据库查询的操作,数据实时性不强,直接加入缓存.当缓存中有的时候,就使用缓存中的数据.这样的方法,最终仅仅使用一个注解实现.对于之前的hibernate二级缓存使用,比较 ...
- [Swift]LeetCode380. 常数时间插入、删除和获取随机元素 | Insert Delete GetRandom O(1)
Design a data structure that supports all following operations in averageO(1) time. insert(val): Ins ...
- openstack快速安装之packstack
最简单的openstack安装方式之packstack 一.环境准备 我们安装的是all-in-one环境的openstack,测试机IP:192.168.1.10 [root@openstack ~ ...
- Spring介绍
Spring介绍 Spring的核心是一个轻量级(Lightweight)的容器(Container),它是实现IoC(Inversion of Control)容器和非入侵性(No intrusiv ...
- AttributeError: module 'pip' has no attribute 'main'
Pycharm在运行pip安装模块是报错如下: 解决方法: 找到安装路径下的packaging_tool.py文件修改如下: 我的路径为D:\Program Files\JetBrains\PyCha ...
- Nginx学习系列三Nginx的启动、停止、修改配置文件后重启
1.启动Nginx 命令规则:Ngxin的安装地址 -c Nginx的安装地址下的配置文件地址 注意:一般都在root权限下进行Nginx的启动 2.停止Nginx (1).从容停止 第一步:查看Ng ...
- asp.net core 系列 10 配置configuration (上)
一. ASP.NET Core 中的配置概述 ASP.NET Core 中的应用配置是基于键值对,由configuration 程序提供. configuration 将从各种配置源提供程序操作键 ...
- 图像识别基本算法之SURF
图像识别.人脸识别可行的算法有很多.但是作为学习,如果能理清这个问题研究的历程及其主线,会对你深入理解当前研究最新的发展有很多帮助.本文是自己在学习过程中的笔记,大多内容来自于网络,出处请参考最后的引 ...