随笔-0  评论-2  文章-61  trackbacks-0

Jvm 的体系结构

一个 jvm 实例运行是要一些内存来存储一些数据 ,jvm 称它为运行时数据区

运行时数据区包括以下几部分

1.       方法区 : 保存类型信息 , 每个类被装载以后 ,jvm 都为他创建一个 Class 类型的实例来代表该类型 , 这些 class 类型的实例都放在堆区

2.       : jvm 把创建的所有对象都放在堆中 ,

3.       java : 由栈帧组成 , 当线程调用一个方法时 , 压入一个帧 , 当返回时弹出一个帧

4.       pc 寄存器 : 指向下一条被执行的指令

5.       本地方法栈 : 用来执行本地方法

其中方法区和堆是所有线程共享的 ,java 栈和 pc 寄存器在每个线程都有一个

 

类型信息包含一下信息 :

1.       这个类型的全限定名

2.       这个类型的直接超类的全限定名 (java.lang.Object 除外 )

3.       这个类型的是类还是接口

4.       这个类型的访问修饰符

5.       这个类型实现的接口的有序列表

除了上面的基本信息外 , 虚拟机还还为每一个装载的类型保存以下信息 :

1.       该类型的常量池 : 什么是常量池呢 ? 就是该类型所用到的所有常量的一个集合 . 包括直接常量如 :3.5 “this is a pen” , 也包括引用常量如 :User user = new User(); user 也算一个常量 .

2.       字段信息 ( 成员变量信息 ): 类型中声明的没一个字段 , 都保存下列信息 :

a.       字段名

b.       字段类型

c.       字段修饰符 (public protected private static 等某个子集 )

3.       方法信息 : 类型中的每个方法都包含了如下信息 :

a.       方法名

b.       方法返回类型

c.       参数的数量和类型

d.       方法修饰符

如果方法不是抽象的和本地的 , 还要保存下列信息

a.       方法的字节码

b.       操作数栈和该方法的栈帧中的局部变量区的大小

c.       异常表

4.       指向 classLoader 的引用 : 如果是用户自定义的 classLoader, 必须在类型信息中存储对该类型的引用

5.       指向 Class 类的引用

 

 

 

 

关于栈帧

       栈帧由三部分组成 :

1.       局部变量区 : 存放局部变量 , 所有的变量被存放在一个数组中 .

局部变量区一般包含的是方法的参数和局部变量 , 编译器按声明的顺序放入数组中

Class A {

  Public static int runClassMethod(int I, long l, float f., double, Object o,. byte b){

        Int a = 100;

        Return a;

  }

}

索引

类型

参数

0

Int

Int i

1

Float

Float f

2

Double(2 字长 )

Double d

3

reference

Object o

4

Int

Byte b

5

Int

Int a

                             局部变量区方法的参数

每个参数至少占用一个字长 ,double long 2 字长

                     在非静态方法中 , 每个方法还隐含一个 this 变量

              java 中所有的对象都存储在堆中 , 永远不会在局部变量区或操作数栈中发现对象的拷贝 , 只会有引用

2.       操作数栈 :

操作数栈也是被组织成一个以字长为单位的数组 , 通过压栈和出栈操作数据 . Jvm 的指令是从操作数栈而不是从寄存器中取得操作数的 .

每个方法都有一个操作数栈 .

操作数栈用来存储将要被指令处理的数据和保存处理完的数据 , 它只是一个临时的存储区 , 运算结果最终还要保存到局部变量区

3.       帧数据区 :

Java 栈帧需要一些数据来支持常量池解析 , 正常方法返回 以及异常派发机制 . 这些信息都保存在 java 栈帧的栈数据区中 .

帧数据区中保存了指向常量池的指针 ( 一个类对应一个常量池 ), 一个方法对应一个栈帧 .

如果方法调用正常返回 , 虚拟机将返回到发起调用的栈帧

帧数据区还必须保存一个对此方法异常表的引用

对异常的处理过程 :

如果方法抛出了异常 , 就去查找异常表 , 如果有匹配的 catch 子句就去处理 , 否则就立刻中止程序 , 然后抛给发起调用的方法的栈帧

posted on 2006-12-22 09:04 comchyi 阅读(203) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: