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) 编辑 收藏