深入理解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更加友好, ...
随机推荐
- ASP.NET文章目录导航
ASP.NET文章目录导航 ASP.NET-[读书笔记]-原创:ASP.Net状态管理读书笔记--思维导图 (2013-12-25 10:13) ASP.NET-[潜在危险]-从客户端中检测到有潜在危 ...
- 使用BroadcastReceiver实现系统对手机电量进行提示
import android.content.BroadcastReceiver;import android.content.Context;import android.content.Inten ...
- cstring 的重载
#include <iostream> #include <windows.h> using namespace std; +; class MyString { public ...
- 获取手机通讯录放入PinnedSectionListView中,按名字首字母排序,并且实现拨打电话功能。
package com.lixu.tongxunlu; import java.util.ArrayList; import com.lixu.tongxunlu.PinnedSectionListV ...
- HDU 4050 wolf5x 概率dp 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=4050 题意: 现在主角站在0处,需要到达大于n的位置 主角要进入的格子有三种状态: 0. 不能进入 1. 能进入 ...
- UVa 11426 - GCD - Extreme (II)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- CodeIgniter 引入自定义公共函数
CodeIgniter 中公共函数不能追加,可以通过 helper 辅助函数实现. 创建 common_helper.php 文件,定义所需公共函数,存放至 application/helpers 目 ...
- JavaScript原生对象属性和方法详解——Array对象
http://www.feeldesignstudio.com/2013/09/native-javascript-object-properties-and-methods-array/ lengt ...
- Flexbox
使用 Flexbox 的牛逼布局 .container { display: -webkit-flex; display: flex; } .initial { -webkit-flex: initi ...
- Linux gcc编译(动态库,静态库)
1. linux 库路径: /lib , /usr/lib , /usr/local/lib 2.linux 编译静态库 a.编写源文件vi pr1.c void print1(){ print ...