JVMS3总结之JVM基本结构

数据类型:

主要分为两种类型的数据: primitive types(基本类型) and reference types(引用类型)

 

基本类型:

• byte :2个bit有符号的二进制补码整数,范围-128 to 127

• short :16个bit有符号的二进制补码整数,范围-128 to 127 

• int :32个bit有符号的二进制补码整数,范围−2147483648 to 2147483647 

• long :64个bit有符号二进制补码整数,范围−9223372036854775808 to 9223372036854775807

• char :16个bit无符号二进制补码整数表示的UTF16字符单元,范围 0 to 65535

• float, whose values are elements of the float value set or, where supported,the float-extended-exponent value set

• double, whose values are elements of the double value set or, where supported,the double-extended-exponent value set

•boolean : true and false. 

   JVM中没有直接操作boolean类型的指令,是先将boolean编译为int类型后才进行操作。对于boolean数组,JVM将其编译为byte数组进行操作。

•returnAddress : JVM指令的操作码的指针。是唯一不在Java语言规范中出现的JVM基本类型。

 

引用类型:

  引用类型只有三种:类、数组、接口, null是所有的类型的子类型。

 

运行时数据区(Runtime Data Area):

  PC Register: 每个Java线程都有属于自己的PC register,如果正在执行的代码属于非native method,则pc register储存着该线程当前正在执行的指令的地址。如果为native method,则JVM Specification不对该PC register的值进行定义。

 

  Stack : 每个Java进程有属于自己的私有栈(stack), 栈中存放的是frame(帧). 

    如果线程的栈超过了JVM规定的大小,则会抛出StackOverflowError,比如过多的递归调用则会出现该错误。

    Stack是动态增长的,如果增长时请求不到足够的内存,则会抛出OutOfMemoryError.

 

  Heap :每个JVM启动时都会创建一个堆,heap存放的是所有的类实例和数组,heap被所有的thread共享。heap中的数据只能被GC回收。当创建新对象(数组)内存不足时,将抛出OutOfMemoryError

 

  Method Area : 方法区被所有的线程共享。存储每个类的结构、常量池、类字段、方法数据、方法和constructor的代码。虚拟机规范指出 Method Area是heap的逻辑部分。因此有说法Sun的jvm是使用Heap的持久区来实现Method Area。当加载新类且内存不足,抛出OutOfMemoryError

 

  Runtime Constant Pool :

    在JVM运行时,运行时常量池存储多种数据,其中就包含以下几种:1, 在编译时即确定的数值型字面量 2, 运行才能确定的常量的字段引用(field references),比如String str="abc"; “abc”在加载该类时会加载到heap中,此时常量池中将会持有该对象的引用。运行时常量池属于Method Area.

 

  Native Method Stacks

    本地方法栈和Stack类似,不过仅仅是为native method服务而已。同样可能抛出StackOverflowError 和 OutOfMemoryError

 

Frame :

  frame用来存储数据、和中间结果、方法的返回值和分发异常。

  当执行一个新方法时,将会创建一个新的帧,当方法结束时,帧也就被销毁。

  帧是由线程的栈分配出来。帧包含本地变量、私有的操作栈、当前类的常量池。

  正在执行的方法所对应的帧称为当前帧(current frame),当方法结束时,当前帧被销毁,执行指令回到前一帧,则前一帧称为当前帧。

  帧是线程的私有财产,不能被多个线程共享。

 

Local Variables (本地变量组?)

  帧包含的一组变量数组称为Local Variables,该数组的长度在编译期就能确定,存放在class文件当中。

  一个Local Variable可以存储boolean, byte, char, short,int, float, reference, or returnAddress,而double,long则需要2个local variable存放。

  Local Variables 和数组一样用下标来表示数组的位置,以0开始。

  JVM使用Local Variables 来传送方法的参数,将调用该方法的实例引用和参数传送过去,下标以0开始。比如类A的实例为a,调用了方法fun(int m, int n),该方法有两个参数。则传送给fun的本地变量数组为[a的引用,m的值,n的值]

 

Operand Stacks

  JVM指令将变量、常量或者方法返回的值放入操作栈中,另一些指令从栈中取出值来进行操作。比如:两个int相加。需要先将这两个int放入该栈,然后再取出来相加,将相加的结果再放入操作栈中。操作栈中的每个实体都能放Java任一数据类型的值。

 

Dynamic Linking

  在class文件中,一个方法是通过符号引来(symbolic references)来表示一个方法调用,frame中包含了一个运行时常量池来对符号进行解释。

 

Exception:

  JVM在以下三种情况下抛出异常:

    1: 比如数组异常、资源不够、加载失败等异常

    2: athrow 指令执行时,比如:throw new Exception()...

    3: 异步异常出现,比如stop来影响其他线程。因为该操作可能发生在其他线程的任一时刻,对于其他线程来将,这样的一场称为异步一场。

 

  当异常发生时,JVM试图在当前方法内寻找该异常的处理者(exception handler),如果找到则将控制权交给该handler。如果找不到,则将该方法内产生的帧、本地变量全部销毁,当前帧退出,并激活调用当前方法的方法(invoking method)的帧为当前帧。并且将异常在当前方法重新抛出。如果一直找不到handler,则该异常所在的线程将会终止。

 

 

 

posted on 2010-12-29 14:48  NanguoCoffee  阅读(674)  评论(0编辑  收藏  举报

导航