深度解析 Java JavaJava内存原型

2017-01-13 15:03:47来源:csdn作者:xiangyunwan人点击


“玩转”Java 系列—————————————————————————————1深度解析 Java JavaJava内存原型一、 JavaJavaJavaJava虚拟机内存原型 虚拟机内存原型寄存器: 寄存器: 我们在程序中无法控制。栈: 存放基本类型的数据和对象引用,但身不在 栈中而是存放基本类型的数据和对象引用,但身不在 栈中而是存放基本类型的数据和对象引用,但身不在 栈中而是存放基本类型的数据和对象引用,但身不在 栈中而是堆中。堆: 存放用 newnew 产生的数据。静态域: 静态域: 存放在对象中用 staticstaticstatic staticstatic定义的静态成员。常量池: 常量池: 存放常量。非 RAMRAMRAM存储: 硬盘等永久存储空间。二、常量池( 二、常量池( constant pool constant poolconstant poolconstant poolconstant poolconstant poolconstant poolconstant poolconstant poolconstant pool constant pool)常量池指的 是在编译期被确定,并保存已的 classclassclass class文件中的一些数 据。除了包含代码中所定义的各种基本类型(如 intintint、longlonglonglong等)和对象型(如 String StringStringStringString及数组)的常量值( finalfinalfinalfinal )外, 还包含一些以文本形式出现的符号引用)外, 还包含一些以文本形式出现的符号引用比如:1、类和接口的全限定名;2、字段的名称和描述符;3、方法的名称和描述符。虚拟机必须为每个被装载的类型维护一常量池。就是该所用到 虚拟机必须为每个被装载的类型维护一常量池。就是该所用到 常量的一个有序集合,包括直接( 常量的一个有序集合,包括直接( 常量的一个有序集合,包括直接( string,integerstring,integerstring,integerstring,integerstring,integerstring,integerstring,integerstring,integerstring,integerstring,integerstring,integer
string,integer 等)和其他类型:字段方 等)和其他类型:字段方 等)和其他类型:字段方 法的符号引用。 对于 StringStringStringStringStringString常量,它的值是在池中 常量,它的值是在池中 常量,它的值是在池中 常量,它的值是在池中 的。 而 JVM JVM中的常量池 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于
在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 在内存当中是以表的形式,对于 String StringStringStringString类型,有一张固定长度的 类型,有一张固定长度的 CONSTANT_String_infoCONSTANT_String_info CONSTANT_String_info
CONSTANT_String_info CONSTANT_String_infoCONSTANT_String_info CONSTANT_String_infoCONSTANT_String_infoCONSTANT_String_infoCONSTANT_String_infoCONSTANT_String_info CONSTANT_String_infoCONSTANT_String_infoCONSTANT_String_info表用来存储文字符串 值,注意:该只表用来存储文字符串 值,注意:该只值,不存储符号引用。说到这里对常量池中的字串位置应该有一个
值,不存储符号引用。说到这里对常量池中的字串位置应该有一个 值,不存储符号引用。说到这里对常量池中的字串位置应该有一个 值,不存储符号引用。说到这里对常量池中的字串位置应该有一个 值,不存储符号引用。说到这里对常量池中的字串位置应该有一个 比较明了的理解。在 程序执行时候,常量池会储存比较明了的理解。在 程序执行时候,常量池会储存Method AreaMethod Area Method AreaMethod AreaMethod AreaMethod AreaMethod Area Method Area
,而不是 堆中。三、 JavaJavaJavaJava内存分配中的栈 内存分配中的栈栈的基本单位是帧(或):每当一个 栈的基本单位是帧(或):每当一个 栈的基本单位是帧(或):每当一个 栈的基本单位是帧(或):每当一个 Java JavaJava线程运行的时候, Java JavaJava虚拟机 会为该线程分配一个 Java JavaJava栈。该线程在执行某个 栈。该线程在执行某个 Java JavaJava方法的时候,向 Java JavaJava栈压 入一个 帧,这用于存储参数、局部变量操作中间运算结果等。当入一个 帧,这用于存储参数、局部变量操作中间运算结果等。当入一个 帧,这用于存储参数、局部变量操作中间运算结果等。当入一个
帧,这用于存储参数、局部变量操作中间运算结果等。当入一个 帧,这用于存储参数、局部变量操作中间运算结果等。当入一个 帧,这用于存储参数、局部变量操作中间运算结果等。当方法执行完的时候,帧会从栈中弹出。 方法执行完的时候,帧会从栈中弹出。 Java JavaJava栈上的所有数据是私,其他线程 栈上的所有数据是私,其他线程 栈上的所有数据是私,其他线程 都不能访问该线程的 栈数据。在函中定义一些基本类型变量和对象都不能访问该线程的 栈数据。在函中定义一些基本类型变量和对象引用变量都在函数的栈内存中分配。当一段代码块定义个时,
引用变量都在函数的栈内存中分配。当一段代码块定义个时, 引用变量都在函数的栈内存中分配。当一段代码块定义个时, Java JavaJava就 在栈中为这个变量分配内存空间, 当该退出作用域后在栈中为这个变量分配内存空间, 当该退出作用域后在栈中为这个变量分配内存空间, 当该退出作用域后Java JavaJava会自动释放掉 为该变量所分配的内存空间,可以立即被另作他用。四、 JavaJavaJavaJava内存分配中的堆 内存分配中的堆“玩转”Java 系列—————————————————————————————2Java JavaJava虚拟机中的堆用来存放由 newnew 创建的对象和数 组。在堆中分配的内存, 组。在堆中分配的内存, 由 Java JavaJava虚拟机的自动垃圾回收制来管理堆内存。简单说和栈相对,主 虚拟机的自动垃圾回收制来管理堆内存。简单说和栈相对,主 要是用来存放 Java JavaJava对象的,栈主要是用来存放引。在堆中产生了一个 对象的,栈主要是用来存放引。在堆中产生了一个 数组或对象后,还可以在栈中定义一个特殊的变量让这取值等于 数组或对象后,还可以在栈中定义一个特殊的变量让这取值等于
数组或对象后,还可以在栈中定义一个特殊的变量让这取值等于 数组或对象在堆内存中的首地址,栈这个变量就成了引用。 数组或对象在堆内存中的首地址,栈这个变量就成了引用。 引用变量就相当于是为数组或对象起的一个名称,以后可在程序中 使栈引用变量就相当于是为数组或对象起的一个名称,以后可在程序中 使栈的引用变量来访问堆中数组或对象。就相当于是为起一 的引用变量来访问堆中数组或对象。就相当于是为起一 个名称。引用变量是普通的,定义时在 栈中分配引用变量是普通的,定义时在 栈中分配引用变量是普通的,定义时在 栈中分配程序运行到其作用 域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到用 newnew 产 生数组或者对象的语句所在代码块之外,和本身占据内存不会被释 生数组或者对象的语句所在代码块之外,和本身占据内存不会被释 放,数组和对象在没有引用变量指向它的时候才为垃圾不能再被使但 放,数组和对象在没有引用变量指向它的时候才为垃圾不能再被使但 放,数组和对象在没有引用变量指向它的时候才为垃圾不能再被使但 放,数组和对象在没有引用变量指向它的时候才为垃圾不能再被使但
放,数组和对象在没有引用变量指向它的时候才为垃圾不能再被使但 仍然占据内存空间不放,在随后的一个确定时被垃圾回收器走(释掉)。 仍然占据内存空间不放,在随后的一个确定时被垃圾回收器走(释掉)。 仍然占据内存空间不放,在随后的一个确定时被垃圾回收器走(释掉)。 仍然占据内存空间不放,在随后的一个确定时被垃圾回收器走(释掉)。 这也是 Java JavaJava比较占内存的原因。实际上,栈中变量指向堆这 比较占内存的原因。实际上,栈中变量指向堆这 就是 Java JavaJava中的指针!java javajava的堆是一个运行时数据区,类对象从中分配空间。这些通过 的堆是一个运行时数据区,类对象从中分配空间。这些通过 的堆是一个运行时数据区,类对象从中分配空间。这些通过 new new new + 构造器等指令建立,它们不需要程序代码 构造器等指令建立,它们不需要程序代码 来显式的释放。堆是由垃圾回收负 来显式的释放。堆是由垃圾回收负 责的, 堆的优势 堆的优势 是可以动态地分配内存大小,生期也不必事先告诉编译器因 是可以动态地分配内存大小,生期也不必事先告诉编译器因 是可以动态地分配内存大小,生期也不必事先告诉编译器因
为它是在运行时动态分配内存的, Java JavaJava的 垃圾收集器会自动走这些不再使用数据。但缺点是,由于要在运行时动态分配内存取速度较慢栈的优势 栈的优势 是存取速度比堆要快, 仅次于寄器栈数据可以共享。但缺点是存取速度比堆要快, 仅次于寄器栈数据可以共享。但缺点是存取速度比堆要快, 仅次于寄器栈数据可以共享。但缺点是存取速度比堆要快, 仅次于寄器栈数据可以共享。但缺点存在栈中的数据大小与生期必须是确定,缺乏灵活性。主要放一些基 存在栈中的数据大小与生期必须是确定,缺乏灵活性。主要放一些基 存在栈中的数据大小与生期必须是确定,缺乏灵活性。主要放一些基 本类型的变量数据( intintint,shortshortshortshortshort,longlonglonglong,bytebytebytebyte,floatfloatfloatfloat
,doubledoubledoubledoubledoubledouble,booleanbooleanbooleanbooleanboolean boolean,charcharchar )和 对象引用。栈有一个很 重要的特殊性,就是存在栈中数据可以共享。假设我们同时定 重要的特殊性,就是存在栈中数据可以共享。假设我们同时定 重要的特殊性,就是存在栈中数据可以共享。假设我们同时定 义: int a=3int a=3int a=3int a=3int a=3 int a=3;int b=3int b=3int b=3int b=3int b=3int b=3 ;编译器先处理 int a = 3int a = 3int a = 3int a = 3int a = 3 int a = 3 int a = 3;首先它会在栈中创建一个变量
为 a的引用,然后查找栈中是否有 的引用,然后查找栈中是否有 的引用,然后查找栈中是否有 3这个值,如果没找到就将 这个值,如果没找到就将 这个值,如果没找到就将 这个值,如果没找到就将 3存放进来,然 存放进来,然 存放进来,然 后将 a指向 3,接着处理 int b = 3int b = 3int b = 3int b = 3int b = 3int b = 3int b = 3int b = 3int b = 3;在创建完 b的引用变量后,因为在栈中已经 有 3这个值,便将 这个值,便将 b直接指向
3这样,就出现了 这样,就出现了 a与 b同时均指向 同时均指向 3的情况。这时,如果再令 这时,如果再令 a=4 a=4;那么编译器会重新搜索栈中是否有 ;那么编译器会重新搜索栈中是否有 ;那么编译器会重新搜索栈中是否有 4值,如果没有则将 值,如果没有则将 值,如果没有则将 值,如果没有则将 4存放进来,并令 a指向 4;如果已经有了,则直接将 ;如果已经有了,则直接将 a指向这个地址 。因此 a值的改变不会影响到 b的值。要注意这种数据的共享与两个对象引用同 时指向一是不要注意这种数据的共享与两个对象引用同 时指向一是不要注意这种数据的共享与两个对象引用同 时指向一是不的,因为这种情况 ,因为这种情况 a的修改并不会影响到 b,它是由编译器完成的,有利于节 ,它是由编译器完成的有利于节 ,它是由编译器完成的有利于节“玩转”Java 系列—————————————————————————————3省空间。而一个对象 引用变量修改了这的内部状态,会影响到另省空间。而一个对象 引用变量修改了这的内部状态,会影响到另省空间。而一个对象 引用变量修改了这的内部状态,会影响到另引用变量。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台