JAVA虚拟机--方法区

  在Java 虚拟机中,被加载类型的信息都保存在方法区中。这些信息在内存中的组织形式由虚拟机的实现者定义,比如,虚拟机工作在一个“little- endian” 的处理器上,他就可以将信息保存为“little-endian” 格式的,虽然在Java 类文件中他们是以“big-endian” 格式保 存的。设计者可以用最适合并地机器的表示格式来存储数据,以保证程序能够以最快的速度执行。但是,在一个只有很小内存的设备上,虚拟机的实现者就不会占用 很大的内存。
    
程序中的所有线程共享一个方法区,所以访问方法区信息的方法必须是线程安全 。如果你有两个线程都去加载一个叫Lava 的类,那只能由一个线程被容许去加载这个类,另一个必须等待。
    
在程序运行时,方法区的大小是可变的,程序在运行时可以扩展。有些Java 虚拟机的实现也可以通过参数也订制方法区的初始大小,最小值和最大值。
    
方法区也可以被垃圾收集。因为程序中的内由类加载器动态加载,所有类可能变成没有被引用(unreferenced )的状态。当类变成这种状态时,他就可 能被垃圾收集掉。没有加载的类包括两种状态,一种是真正的没有加载,另一个种是“unreferenced” 的状态。 详细信息参见第七章的类的生命周期 (The Lifetime of a Class )。
     1
、类型信息(Type Information
         
每一个被加载的类型,在Java 虚拟机中都会在方法区中保存如下信息:
          1
)、类型的全名(The fully qualified name of the type
          2
)、类型的父类型的全名(除非没有父类型,或者弗雷形式java.lang.Object )(The fully qualified name of the typeís direct superclass
          3
)、给类型是一个类还是接口(class or an interface )(Whether or not the type is a class
          4
)、类型的修饰符(publicprivateprotectedstaticfinalvolatiletransient 等)(The typeís modifiers
          5
)、所有父接口全名的列表(An ordered list of the fully qualified names of any direct superinterfaces
         
类型全名保存的数据结构由虚拟机实现者定义。除此之外,Java 虚拟机还要为每个类型保存如下信息:
          1
)、类型的常量池(The constant pool for the type
          2
)、类型字段的信息(Field information
          3
)、类型方法的信息(Method information
          4
)、所有的静态类变量(非常量)信息(All class (static) variables declared in the type, except constants
          5
)、一个指向类加载器的引用(A reference to class ClassLoader
          6
)、一个指向Class 类的引用(A reference to class Class


          1
)、类型的常量池(The constant pool for the type
         
常量池中保存中所有类型是用的有序的常量集合,包含直接常量(literals )如字符串、整数、浮点数的常量,和对类型、字段、方法的符号引用。常量池 中每一个保存的常量都有一个索引,就像数组中的字段一样。因为常量池中保存中所有类型使用到的类型、字段、方法的字符引用,所以它也是动态连接的主要对 象。
          2
)、类型字段的信息(Field information
         
字段名、字段类型、字段的修饰符(publicprivateprotectedstaticfinalvolatiletransient 等)、字段在类中定义的顺序。
          3
)、类型方法的信息(Method information
         
方法名、方法的返回值类型(或者是void )、方法参数的个数、类型和他们的顺序、字段的修饰符(publicprivateprotectedstaticfinalvolatiletransient 等)、方法在类中定义的顺序
         
如果不是抽象和本地本法还需要保存
         
方法的字节码、方法的操作数堆栈的大小和本地变量区的大小(稍候有详细信息)、异常列表(详细信息参见第十七章“Exceptions” 。)
          4
)、类(静态)变量 Class Variables
         
类变量被所有类的实例共享,即使不通过类的实例也可以访问。 这些变量绑定在类上(而不是类的实例上),所以他们是类的逻辑数据的一部分。在Java 虚拟机使用这个类之前就需要为类变量(non-final )分配内存
         
常量(final )的处理方式于这种类变量(non-final )不一样。每一个类型在用到一个常量的时候,都会复制一份到自己的常量池中。常量也像类变 量一样保存在方法区中,只不过他保存在常量池中。(可能是,类变量被所有实例共享,而常量池是每个实例独有的)。Non-final 类变量保存为定义他的 类型数据(data for the type that declares them )的一部分,而final 常量保存为使用他的类型数据(data for any type that uses them )的一部分。

          5 )、指向类加载器的引用(A reference to class ClassLoader
         
每一个被Java 虚拟机加载的类型,虚拟机必须保存这个类型是否由原始类加载器或者类加载器加载。那些被类加载器加载的类型必须保存一个指向类加载器的引 用。当类加载器动态连接时,会使用这条信息。当一个类引用另一个类时,虚拟机必须保存那个被引用的类型是被同一个类加载器加载的,这也是虚拟机维护不同命 名空间的过程。详情参见第八章“The Linking Model”
          6
)、指向Class 类的引用(A reference to class Class
          Java
虚拟机为每一个加载的类型创建一个java.lang.Class 类的实例。你也可以通过Class 类的方法:public static Class forName(String className) 来查找或者加载一个类,并取得相应的Class 类的实例。 通过这个Class 类的实例,我们可以访问Java 虚拟机方法区中的信息。具体参照Class 类的JavaDoc
     2
、方法列表(Method Tables
    
为了更有效的访问所有保存在方法区中的数据,这些数据的存储结构必须经过仔细的设计。所有方法区中,除了保存了上边的那些原始信息外,还有一个为了加快存 取速度而设计的数据结构,比如方法列表。每一个被加载的非抽象类,Java 虚拟机都会为他们产生一个方法列表,这个列表中保存了这个类可能调用的所有实例 方法的引用,报错那些父类中调用的方法。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值