深入理解JVM内部结构(转)
- boolean
- byte
- char
- long
- short
- int
- float
- double
- reference
- returnAddress
除了long和double,所有的类型都在局部变量数组中占据一个位置,long及double则占用两个连续的位置(slot),由于它们是双倍的宽度,也即64位大小。
- int i;
编译以后的字节码如下:
- 0: iconst_0 // Push 0 to top of the operand stack
- 1: istore_1 // Pop value from top of operand stack and store as local variable 1
- Young Generation(年轻代),通常被分为Eden和Survivor
- Old Generation(老年代,也叫Tenured Generation)
- Permanent Generation
(2) 内存管理
- 类加载器引用
- 运行时常量池
- 数值常量
- 字段引用
- 方法引用
- 属性值
- 字段数据
- 每个字段
- 名称
- 类型
- Modifiers
- 属性值
- 每个字段
- 方法数据
- 每个方法
- 名称
- 返回类型
- 参数类型
- Modifiers
- 属性值
- 每个方法
- 方法代码
- 每个方法
- 字节码
- 操作对象栈大小
- 局部变量大小
- 局部变量表
- 异常表
- 每个异常处理器
- 起始点
- 结束点
- 处理器代码的PC偏移值
- 捕抓的异常类的常量池索引
- 每个异常处理器
- 每个方法
所有的线程共享相同的方法区,因此方法区数据的存取及动态链接的过程必须是线程安全的。如果两个线程都企图存取同一个类中的字段或方法,但是,此类还没有被加载,则它必须只被加载一次,并且线程必须等到类被加载完成以后才能继续执行。
- ClassFile {
- u4 magic;
- u2 minor_version;
- u2 major_version;
- u2 constant_pool_count;
- cp_info contant_pool[constant_pool_count – 1];
- u2 access_flags;
- u2 this_class;
- u2 super_class;
- u2 interfaces_count;
- u2 interfaces[interfaces_count];
- u2 fields_count;
- field_info fields[fields_count];
- u2 methods_count;
- method_info methods[methods_count];
- u2 attributes_count;
- attribute_info attributes[attributes_count];
- }
如果你想看一个编译完成的类文件的字节码,可以使用命令行工具javap。
- package org.jvminternals;
- public class SimpleClass {
- public void sayHello() {
- System.out.println("Hello");
- }
- }
- public class org.jvminternals.SimpleClass
- SourceFile: "SimpleClass.java"
- minor version: 0
- major version: 51
- flags: ACC_PUBLIC, ACC_SUPER
- Constant pool:
- #1 = Methodref #6.#17 // java/lang/Object."<init>":()V
- #2 = Fieldref #18.#19 // java/lang/System.out:Ljava/io/PrintStream;
- #3 = String #20 // "Hello"
- #4 = Methodref #21.#22 // java/io/PrintStream.println:(Ljava/lang/String;)V
- #5 = Class #23 // org/jvminternals/SimpleClass
- #6 = Class #24 // java/lang/Object
- #7 = Utf8 <init>
- #8 = Utf8 ()V
- #9 = Utf8 Code
- #10 = Utf8 LineNumberTable
- #11 = Utf8 LocalVariableTable
- #12 = Utf8 this
- #13 = Utf8 Lorg/jvminternals/SimpleClass;
- #14 = Utf8 sayHello
- #15 = Utf8 SourceFile
- #16 = Utf8 SimpleClass.java
- #17 = NameAndType #7:#8 // "<init>":()V
- #18 = Class #25 // java/lang/System
- #19 = NameAndType #26:#27 // out:Ljava/io/PrintStream;
- #20 = Utf8 Hello
- #21 = Class #28 // java/io/PrintStream
- #22 = NameAndType #29:#30 // println:(Ljava/lang/String;)V
- #23 = Utf8 org/jvminternals/SimpleClass
- #24 = Utf8 java/lang/Object
- #25 = Utf8 java/lang/System
- #26 = Utf8 out
- #27 = Utf8 Ljava/io/PrintStream;
- #28 = Utf8 java/io/PrintStream
- #29 = Utf8 println
- #30 = Utf8 (Ljava/lang/String;)V
- {
- public org.jvminternals.SimpleClass();
- Signature: ()V
- flags: ACC_PUBLIC
- Code:
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: return
- LineNumberTable:
- line 3: 0
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 5 0 this Lorg/jvminternals/SimpleClass;
- public void sayHello();
- Signature: ()V
- flags: ACC_PUBLIC
- Code:
- stack=2, locals=1, args_size=1
- 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
- 3: ldc #3 // String "Hello"
- 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
- 8: return
- LineNumberTable:
- line 6: 0
- line 7: 8
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 9 0 this Lorg/jvminternals/SimpleClass;
- }
- 常量池, 它提供了与符号表相同的信息,这个将在后面进行详述。
- 方法, 每个方法包含了四个部分:
- 签名及访问标记
- 字节码
- 行号表, 它主要用于为调试器提供信息,行号表指示了每个字节码指令对应的行数,如Java代码中的第六行对应了sayHello方法中的字节码0,第七行对应了字节码8.
- 局部变量表, 它列出了帧中提供的所有局部变量,在本例子中,只有this这一个局部变量。
此类文件中使用到的字节码操作数有:
|
aload_0
|
此操作码是格式为aload_<n>的操作码组的成员之一,它们都是用于加载一个对象引用到操作
对象栈中. <n>指示了对象在局部变量数组中的位置,可选的数字只能是0,1,2,3之一。还有其它类似的操作
码用于加载数值,而非对象引用。如iload_<n>,lload_<n>, fload_<n>和dload_<n>,其中i是指int类型
l是long,f是float,d是double类型。对于索引值超过3的局部变量,可以使用iload,lload,fload,dload进行
加载。这些操作码都只有一个操作数,用于指定要加载的局部变量的索引。
|
|
ldc
|
这个指令(操作码)用于将一个运行时常量池中的常量压入操作对象栈中
|
|
getstatic
|
此指令用于将运行时常量池的静态字段列表中的一个静态值压入到操作对象栈中。
|
|
invokespecial,
invokevirtual
|
这两个指令属于调用方法的指令组成员之一,调用方法的指令有:invokedynamic,invokestatic,
invokevirtual。在这个类文件中,invokevirtual用于基于对象的类进行方法调用,而invokespecial指令则用
于调用当前类的实例初始化方法,私有方法及父类方法。
|
|
return
|
此指令时返回型指令组成员之一,其它的还有ireturn,lreturn,freturn,dreturn,areturn及
return。每个指令都是一类返回不同类型数值的返回声明,i是int类型,l是long,f是float,d是
double,a则是对象引用。没有前置类型字符的return则是返回void类型。
|




- 数值型字面值
- 字符串字面值
- 类引用
- 字段引用
- 方法引用
如下面的代码:
- Object foo = new Object();
其对应的字节码如下:
- 0: new #2 // Class java/lang/Object
- 1: dup
- 2: invokespecial #3 // Method java/ lang/Object "<init>"( ) V
- 起始点
- 结束点
- 处理器代码的PC偏移值
- 被捕抓的异常类的常量池索引
如果一个方法定义了一个try-catch或try-finally异常处理器,则一个异常表将会被创建。异常表包含了每个异常处理器或者是finally块的信息,如异常处理应用的范围,那种类型的异常会被处理及异常处理代码所在的位置。
转载地址:http://blog.csdn.net/huaishu/article/details/9844257
深入理解JVM内部结构(转)的更多相关文章
- 深入理解JVM内幕(转)
转自:http://blog.csdn.net/zhoudaxia/article/details/26454421/ 每个Java开发者都知道Java字节码是执行在JRE((Java Runtime ...
- 深入理解JVM内幕:从基本结构到Java 7新特性
转自:http://www.importnew.com/1486.html 每个Java开发者都知道Java字节码是执行在JRE((Java Runtime Environment Java运行时环境 ...
- [译]深入理解JVM
深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...
- 转:深入理解jvm
深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...
- 【转】[译]深入理解JVM
http://www.cnblogs.com/enjiex/p/5079338.html 深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/un ...
- 深入理解JVM内幕:从基本结构到Java 7新特性[转]
英文原文:cubrid,编译:ImportNew - 朱伟杰 译文链接:http://www.importnew.com/1486.html [如需转载,请在正文中标注并保留原文链接.译文链接和译者等 ...
- 深入理解 JVM 的内存区域
深入理解运行时数据区 代码示例: 1. JVM 向操作系统申请内存: JVM 第一步就是通过配置参数或者默认配置参数向操作系统申请内存空间,根据内存大小找到具体的内存分配表,然后把内存段的起始地址和终 ...
- 深入理解JVM垃圾收集机制(JDK1.8)
垃圾收集算法 标记-清除算法 最基础的收集算法是"标记-清除"(Mark-Sweep)算法,分两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. 不足: ...
- 深入理解JVM(一)编译openJDK
此文总结的很不错:https://www.cnblogs.com/ACFLOOD/p/5528035.html 准备openJDK源码和环境 1.在linux和macOS上编译openJDK更加友好, ...
随机推荐
- 并发容器之CopyOnWriteArrayList
原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...
- 生成guid
http://jingyan.baidu.com/article/84b4f565eebb9d60f6da3293.html
- linux ps命令介绍
来源<鸟哥的linux私房菜> ps:将某个时间点的程序运作情况撷取下来 [root@linux ~]# ps aux [root@linux ~]# ps -lA [root@linux ...
- iOS不显示状态栏(电池和信号栏)
//隐藏状态栏 - (BOOL)prefersStatusBarHidden { return YES; } 在viewcontroller里面加入
- ARM2440 LCD实验
1. S3C2440内部LCD控制器结构图: 我们根据数据手册来描述一下这个集成在S3C2440内部的LCD控制器: a:LCD控制器由REGBANK.LCDCDMA.TIMEGEN.VIDPRCS寄 ...
- Java与.NET DES加密解密互转
上代码: Java代码: import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKe ...
- VS2013项目配置directx11
假定你已经安装好了direct11 SDK(官方下的既是最新版本)和VS2013,并在VS2013中建立了一个新工程. 用VS2013打开工程后,点击右键属性,选择VC++目录: 其中在包含目录中添加 ...
- SharePoint 沙盒解决方案 VS 场解决方案
博客地址 http://blog.csdn.net/foxdave 最近看书正好看到了关于沙盒解决方案的介绍,便整理记录一下. 虽然沙盒解决方案已经在最新的SharePoint开发中被否决弃用了(被A ...
- XCode 自动化打包总结
最近一个礼拜折腾xcode 中ipa 自动化打包,对我来说也说是磕磕碰碰.毕竟对mac下的命令行模式完全不熟悉.而且我们的项目是基于cordova的一个项目. 之前我自己对cordova 项目的命令行 ...
- 详解模块定义(.def)文件
一个完整的Windows应用程序(C++程序)通常由五种类型的文件组成:源程序文件,头文件,资源描述文件,项目文件,模块定义文件.本文主要讲解模块定义文件. 模块定义 (.def)文件为链接器提供有关 ...