Java内存模型——方法区

方法区(Method Area)

①      对每个加载的类型,JVM必须在方法区中存储以下类信息:

1)        这个类型的完整有效名(类型信息

类型名称在Java类文件和JVM中都以完整有效名出现。在java源代码中,完整有效名由类的所属包名称加一个".",再加上类名组成。例如,类Object的所属包为java.lang,那它的完整有效名为java.lang.Object,但在类文件里,所有的"."都被斜杠“/”代替,就成为java/lang/Object。完整有效名在方法区中的表示根据不同的实现而不同。

2)        这个类型直接父类的完整有效名(除非这个类型是interface或是 java.lang.Object,两种情况下都没有父类

3)        这个类型的修饰符(Public,Abstract, Final的某个子集)

4)        这个类型直接接口的一个有序列表

②      除了以上的基本信息外,JVM还要为每个类型保存以下信息:

1)        类型的常量池(Constant Pool)

JVM为每个已加载的类型都维护一个常量池

常量池就是这个类型用到的常量的一个有序集合,包括实际的常量/字面量(StringInteger和Floating Point浮点常量)和对类型,域和方法的符号引用。池中的数据项象数组项一样,是通过索引访问的。 因为常量池存储了一个类型所使用到的所有类型方法的符号引用

字面量:是用于表达源代码中一个固定值的表示法(如文本字符串,声明为final的常量值等)

常量: (被声明为final的类变量)每个常量都会在常量池中有一个拷贝。non-final类变量被存储在声明它的类信息内,而final类被存储在所有使用它的类信息内。

符号引用:(符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可—保证唯一性)类和接口的全限定名、 字段的名称和描述符、方法的名称和描述符。符号引用与虚拟机的内存布局无关,引用的目标并不一定加载到内存中。Java中,一个java类将会编译成一个class文件。在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替。(类似于CONSTANT_Class_info的常量来表示的)

常量池在Java程序的动态链接(运行期间也可能将新的常量放入池中)中起了核心的作用。

2)        域(Field)信息 (字段信息)

JVM必须在方法区中保存类型的所有域的相关信息以及域的声明顺序, 域的相关信息包括: 域名域类型域修饰符(public,private, protected,static,final,volatile,transient的某个子集)

域:域是一种属性,可以是一个类变量(类的静态变量),一个对象变量,一个对象方法变量或者是一个函数的参数

3)        方法信息

JVM必须保存所有方法的一下信息,同域信息一样包含声明顺序,方法名方法返回的类型(也可以是void)、方法参数的数量和类型(有序的)、方法的修饰符(public, private, protected, static, final, synchronized, native, abstract的一个子集)除了abstract和native方法外,其他方法还有保存方法的字节码(bytecodes)、操作数栈和方法栈帧的局部变量区的大小异常表

4)        类变量(除了常量外的所有静态(static)变量)

类变量(类的静态变量)被类的所有实例共享,即使没有类实例时你也可以访问它。这些变量只与类相关,所以在方法区中,它们成为类数据在逻辑上的一部分。在jvm使用一个类之前,它必须在方法区中为每个non-final类变量分配空间。

5)        指向类加载器的引用

每一个被JVM加载的类型,都保存这个类加载器的引用,类加载器动态链接时会用到。

时间: 2024-08-03 12:55:07

Java内存模型——方法区的相关文章

java内存区域-方法区

方法区(Method Area)与java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据.虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与java堆分开.

Java内存模型与JVM运行时数据区的区别

首先,这两者是完全不同的概念,绝对不能混为一谈. 1.什么是Java内存模型? Java内存模型是Java语言在多线程并发情况下对于共享变量读写(实际是共享变量对应的内存操作)的规范,主要是为了解决多线程可见性.原子性的问题,解决共享变量的多线程操作冲突问题. 多线程编程的普遍问题是: 所见非所得 无法肉眼检测程序的准确性 不同的运行平台表现不同 错误很难复现 故JVM规范规定了Java虚拟机对多线程内存操作的一些规则,主要集中体现在volatile和synchronized这两个关键字. vo

java case 3:方法区(PermGen)内存快速飙升问题

欢迎访问:http://www.cloudnoter.com/?p=143 自从平台升级到3.0后,应用的JVM变得非常不稳定,主要体现为以下三个问题: 1.内存泄漏:2G的JVM,2天就崩. 2.方法区内存持续飙升,最终导致频繁的触发FullGC 3.class load频繁导致CPU有30%的资源浪费 在写之前先吐槽下:这个自研的JPA组件真TM坑人,放着开源的不用,非得自己实现,三个问题都是自研的JPA组件引入. 解决方案: 问题1: 问题1相对好解决,先用jmap将堆快照dump出来,用

深入理解Java内存模型(1 ) -- 基础(转载)

原文地址:http://www.infoq.com/cn/articles/java-memory-model-1 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.在消息传递的并发模型里,线程之间没有公共状态,线

对java内存模型的认识

浅谈java内存模型        不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结java的内存模型,要解决两个主要的问题:可见性和有序性.我们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的.JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节,对于java开发人员,要清楚在jvm内存模型的基础上,如果解决多线程的可见性和有序性

java内存模型与线程(转) good

java内存模型与线程 参考 http://baike.baidu.com/view/8657411.htm http://developer.51cto.com/art/201309/410971_all.htm http://www.cnblogs.com/skywang12345/p/3447546.html 计算机的CPU计算能力超强,其计算速度与 内存等存储 和通讯子系统的速度相比快了几个数量级, 数据加载到内存中后,cpu处理器运算处理时,大部分时间花在等待获取去获取磁盘IO.网络通

Java内存模型与垃圾回收

1.Java内存模型 Java虚拟机在执行程序时把它管理的内存分为若干数据区域,这些数据区域分布情况如下图所示: 程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是Native方法,这个计算器值为空. Java虚拟机栈:线程私有的,其生命周期和线程一致,每个方法执行时都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息. 本地方法栈:与虚拟机栈功能类似,只不过虚拟机栈为虚拟机执行J

深入理解Java内存模型之系列篇[转]

原文链接:http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. see:命令式编程.函数式编程 在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存

java内存模型详解

内存模型 (memory model) 内存模型描述的是程序中各变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节. 不同平台间的处理器架构将直接影响内存模型的结构. 在C或C++中, 可以利用不同操作平台下的内存模型来编写并发程序. 但是, 这带给开发人员的是, 更高的学习成本.相比之下, java利用了自身虚拟机的优势, 使内存模型不束缚于具体的处理器架构, 真正实现了跨平台.(针对hotspot jvm, jrockit等不同的