Java的内存分配

来源:互联网 发布:淘宝在国外的影响力 编辑:程序博客网 时间:2024/06/05 02:42

★Java程序运行时的内存结构分成:方法区、栈内存、堆内存、本地方法栈几种。(还有一个寄存器区,我们在程序中无法控制。这些内存区块都是由JVM负责维护。)

方法区:

存放被装载类的数据信息,即存放该类的定义信息。类装载之后,类的定义(.class字节码)存放在方法区。具体信息包括:

1、基本信息:
)每个类的全限定名
2)每个类的直接超类的全限定名(可约束类型转换)
3)该类是类还是接口(类型)
4)该类型的访问修饰符
5)直接超接口的全限定名的有序列表

2、每个已装载类的详细信息:
1) 运行时常量池:存放该类型所用的一切常量(直接常量和对其它类型、字段、方法的符号引用),它们以数组形式通过索引被访问,是外部调用与类联系及类型对象化的桥梁。它是类文件(字节码)常量池的运行时表示。(还有一种静态常量池,在字节码文件中)
2) 字段信息:类中声明的每一个字段的信息(名,类型,修饰符)。
3) 方法信息:类中声明的每一个方法的信息(名,返回类型,参数类型,修饰符,方法的字节码和异常表)。
4) 静态变量
5) 到类classloader的引用:即到该类的类装载器的引用。
6) 到类class的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。

◆全限定名:带包结构的类名◆非静态常量存放在运行时常量池中,静态常量存放在字节码文件中的静态常量池。(静态常量存放在静态常量池。而静态变量、非静态常量、字段信息、普通方法和构造方法等都存放在方法区。)◆静态常量是所有类都共用的,而静态变量只是当前类的所有对象共用。◆字段即属性,都来自英文field,也称成员变量。◆相当于你写的一个类(的定义),JVM把它(JVM拿到的是.class字节码的形式)大卸八块,全部存放在方法区(以“变量=值”的形式存放),在以后需要用哪一块时随时取出来。◆总结:总之,一句话,方法区存放的是一个类定义时所包含的所有信息(注意,它站的位置是“类”的层次,是所有对象共用或相同的信息)

栈内存:

Java栈内存以帧的形式存放本地方法的调用状态(包括方法调用的参数,局部变量,中间结果等)。也就是说:在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配。

栈内存的构成:由局部变量区、操作数栈、帧数据区组成。

1、局部变量区为一个以字为单位的数组,每个数组元素对应一个局部变量的值。调用方法时,将方法的局部变量组成一个数组,通过索引来访问。若为非静态方法,则加入一个隐含的引用参数this,该参数指向调用这个方法的对象。而静态方法则没有this参数。因此,对象无法调用静态方法。

2、操作数栈也是一个数组,但是通过栈操作来访问。所谓操作数是那些被指令操作的数据。当需要对参数操作时如a=b+c,就将即将被操作的参数压栈,如将b和c压栈,然后由操作指令将它们弹出,并执行操作。虚拟机将操作数栈作为工作区。

3、帧数据区处理常量池解析,异常处理等。

栈内存存放的是:(1)基本数据类型数据的值;(2)变量的内存分配的地址。帧的形式:指类似一格一格的形式,每一帧就是栈中的一个数据。调用状态:说明是运行起来的,在动的,不是静的。总之,操作数栈存放的是:(1)基本数据类型数据的值;(2)引用变量的内存分配的地址。

堆内存:

用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

栈内存和堆内存比较:
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本数据类型的变量(int, short, long,byte,float,double,boolean,char)和对象句柄。

本地方法栈内存:
Java通过本地JNI(Java Native Interface)来调用其它语言编写的程序,用native修饰符来描述一个方法是本地方法。

堆内存:存放的是new创造的内存空间,即new的东西都是存放在堆中。栈内存中的数据,Java虚拟机不负责回收垃圾。因为栈中一般存放的是临时变量,用完(出了作用域)之后会自己维护清理弹出栈的。方法区是不存在内存清理的,因为一个类中的方法等信息以后可能还会用,不能清除,只有在虚拟机关闭时才会清理。JNI是Java Native Interface的缩写,中文为JAVA本地调用。它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是CC++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用JNI通常会丧失平台可移植性,该项技术已经用得越来越少了。
原创粉丝点击