深入理解java虚拟机一 JAVA运行时内存区域与class文件

一 JAVA运行时内存区域

JVM在加载class文件时,会将class文件定义的数据结构转为运行时内存中的数据,那么jvm是如何安排运行时的内存区域呢?

jvm将运行时内存划分为以下几个部分:

堆:所有线程共享

方法区:类信息、静态变量、常量等

  运行时常量池:class文件的常量池(字面常量和符号引用)+运行时产生的常量

程序计数器:  当前线程执行的字节码的行号指示器

虚拟机栈:栈帧 = 本地局部变量表、操作数栈、动态链接、出口信息

本地方法栈:native方法

直接内存:不属于jvm管理,但是在nio中,会使用native方法申请堆外内存,并在java堆中保存其引用。

其中,堆和方法区是所有的线程所共享的,而虚拟机栈、本地方法栈和程序计数器是各线程所独享的。

二 class文件

class文件是怎样定义的呢?它与java运行时内存是什么关系呢?

class文件格式:

u4 魔数

u2 class文件版本号

u2 class文件版本号

u2 constant_pool_count    表示常量池容量大小,从1开始计数;

   常量池中主要存放两大类:字面常量和符号引用

     符号引用又包含三类:类、接口的全限定名,字段名称和描述,方法名称和描述

    注意这里会定义字段常量与方法常量。与后面的字段表/方法表略有不同,但是会复用相同的简单名称和描述符。

cp_info constant_pool

   共定义了11种常量项

u2 access_flag

  是否是类/接口,是否是抽象类,是否是private等,是否是final等

u2 this_class

u2 super_class

u2 interface_count

u2 interfaces

都是指 常量池中的全限定名称,先指向类/接口索引,再找到utf-8的索引

u2 fields_count

field_info fields

字段表中会包含 字段access属性、字段名称索引、描述符索引以及attribute;

描述符:数组 [, V void, L 引用类型, 描述方法时,先用小括号描述参数列表,后面再跟上返回值描述。

字段表中不会列出父类和超类中继承而来的字段名

u2 methods_count

method_info methods

方法表:access属性,名称索引、描述索引以及attribute

如果方法没有被override,则不会出现父类继承而来的方法名

u2 attributes_count

attribute_info attributes

属性表中最重要的要数方法表的Code属性,其中包含了方法的具体信息,具体如下:

u2 attribute_name_index

u4 attribute_length

u2 max_stack 操作数栈的最大深度

u2 max_locals

u4 code_length

u1 code * code_length

....异常表等

时间: 2024-10-22 11:03:07

深入理解java虚拟机一 JAVA运行时内存区域与class文件的相关文章

深入理解Java虚拟机读书笔记---运行时数据区域

运行时数据区域 1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支.循环.跳转.异常处理.线程恢复等基础功能都需要依赖这个计数器来完成.由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令.因此,为了线

Java虚拟机学习--记录运行时数据区域

为方便后面学习的理解,记录一下! 运行时数据区 1.线程共享 1.1方法区(Method Area) 1.1.1运行时常量池(Runtime Constant Pool) 1.2堆(Heap) 2.线程私有 2.1虚拟机栈(VM Stack) 2.2本地方法栈(Native Method Stack) 2.3程序计数器(Program Counter Register) 3.直接内存(Direct Memory) 虚拟机栈: 线程私有,生命周期与线程同步,用来执行Java方法. 每个java方法

你还在看《深入理解Java虚拟机》的运行时数据模型吗?

学习JVM必看的书籍无疑是<深入理解Java虚拟机>这本书了,在书中,关于运行时数据区域模型是这样描述的: 在这里我们只针对HotSpot VM来说,它是OracleJDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机.在JDK7之前,这样的模型是正确的.但是到了JDK8,如图标红的部分,做了一些优化. 什么是方法区,什么是永久代,运行时常量池又是什么 "方法区"(Method Area),是线程共享的区域,用于存储已被虚拟机加载的类信息,常量,静态变

java虚拟机学习(一) 内存区域

java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个区域,包含方法区域,堆,虚拟机栈,本地方法栈,程序计数器,其中方法区域和堆是所有线程共享的数据区.结构如图: 程序计数器: 占的空间较小,可以看作是字节码行号指示器,字节码解析器是通过改变它的值来选取下一条字节码指令, 分支,循环,跳转,异常处理,线程恢复等 ,都依赖它来完成.每一条线程都有独立的一个计数器,也可以看作是私有内存,如果执行本地方法,这个计数器则为空, 该区域是唯一的一个没有OutOfMemory情况的区域. J

Java虚拟机OOM之运行时常量池溢出(5)

如果要向运行时常量池中添加内容,最简单的做法就是使用 String.intern()这个 Native 方法.该方法的作用是:如果池中已经包含一个等于此 String 对象的字符串,则返回代表池中这个字符串的String 对象:否则,将此 String 对象包含的字符串添加到常量池中,并且返回此 String 对象的引用.由于常量池分配在方法区内,我们可以通过-XX:PermSize 和-XX:MaxPermSize 限制方法区的大小,从而间接限制其中常量池的容量代码运行时常量池导致的内存溢出异

深入理解Java虚拟机:运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里

《深入理解java虚拟机》笔记(1)运行时数据区域

1.Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. 2.运行时数据区域划分 java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个区域,这些区域都有各自的用途,创建和销毁时间,有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户线程的启动和结束而建立和销毁,根据<Java虚拟机规范(Java SE 7版)>的规定,java虚拟机分为以下区域. 2.1.程序计数器(Program Counter Register)

Java虚拟机 - 结构原理与运行时数据区域

http://liuwangshu.cn/java/jvm/1-runtime-data-area.html 前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关知识,Java虚拟机也并不是三言两语能够介绍完的,因此开了Java虚拟机系列,这一篇文章我们来学习Java虚拟机的结构原理与运行时数据区域. 1.Java虚拟机概述 Oracle官方定义的Java技术体系主要包括以下几个部分: Java程序设计语言 各种平台的Java虚拟机 Class文件格式 Ja

Java虚拟机(一)结构原理与运行时数据区域

前言 本来计划要写Android内存优化的,觉得有必要在此之前介绍一下Java虚拟机的相关知识,Java虚拟机也并不是三言两语能够介绍完的,因此开了Java虚拟机系列,这一篇文章我们来学习Java虚拟机的结构原理与运行时数据区域. 1.Java虚拟机概述 Oracle官方定义的Java技术体系主要包括以下几个部分: Java程序设计语言 各种平台的Java虚拟机 Class文件格式 Java API类库 第三方Java类库 可以把Java程序设计语言.Java虚拟机和Java API类库这三部分