JVM内存分配原理
2020-06-01 18:07:56 0 举报
JVM内存分配原理
作者其他创作
大纲/内容
对象类型数据
test:0x111reference
局部变量表
堆--被所有线程共享的一块内存区域,在虚拟机启动时创建,唯一目的就是存放对象实例(数组),是垃圾回收器管理的主要区域,可细分为新生代和老年代,java堆可以处于物理上不连续的内存空间中
2
栈(线程私有)--生命周期与线程相同,每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口 一个方法开始执行和结束,对应入栈出栈
3
静态区--放静态变量和静态代码块
老年区(代)
永久区
i
1.运行时常量池:在方法区中,每个类型都对应一个常量池,存放该类型所用到的所有常量,常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。它们以数组形式通过索引被访问,是外部调用与类联系及类型对象化的桥梁。(存的可能是个普通的字符串,然后经过常量池解析,则变成指向某个类的引用)
包括
1
class Test3{ String name=\"baba1\"; int age;}Test3 test=new Test3();test.age=3test.name=bab
package org.fenixsoft.clazz;public class TestClass { private int m; public int inc() { return m + 1; }}上述代码运行时常量池为Constant pool:const #1 = class #2; // org/fenixsoft/clazz/TestClassconst #2 = Asciz org/fenixsoft/clazz/TestClass;const #3 = class #4; // java/lang/Objectconst #4 = Asciz java/lang/Object;const #5 = Asciz m;const #6 = Asciz I;const #7 = Asciz <init>;const #8 = Asciz ()V;const #9 = Asciz Code;const #10 = Method #3.#11; // java/lang/Object.\"<init>\":()Vconst #11 = NameAndType #7:#8;// \"<init>\":()Vconst #12 = Asciz LineNumberTable;const #13 = Asciz LocalVariableTable;const #14 = Asciz this;const #15 = Asciz Lorg/fenixsoft/clazz/TestClass;;const #16 = Asciz inc;const #17 = Asciz ()I;const #18 = Field #1.#19; // org/fenixsoft/clazz/TestClass.m:Iconst #19 = NameAndType #5:#6; // m:Iconst #20 = Asciz SourceFile;const #21 = Asciz TestClass.java;
类的详细信息
对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
jdk1.7 将字符串常量池和静态区移入堆中jdk1.8之后,元空间替代永久代,并将永久代中剩余的东西全部移入元空间
null
伊甸园区
test2
具体包括:看上面
4
方法区(为堆的逻辑部分,但被称为非堆,为的是和堆区分开来)--是各个线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,垃圾收集行为在这个区域比较少见
test:name:bab1age:4
局部变量表(演示对象创建)
幸存区01
包括1.每个类的全限定名 com.xue.pojo.Test2.每个类的直接超类的全限定名(可约束类型转换)3.该类是类还是接口 4.该类型的访问修饰符5.直接超接口的全限定名的有序列表
类的基本信息
程序计数器(当前线程所执行的字节码的行号指示器)--字节码指示器工作是通过改变计数器的值来选取下一条需要执行的字节码指令
本地方法栈--为虚拟机使用到的native方法服务
局部变量表--存放编译期可知的各种基本数据类型、对象引用 局部变量表所需的内存空间在编译期间完成分配
对象创建:class Test3{ String name=\"baba1\
运行时常量池(方法区的一部分)--用于存放编译时期生成的各种字面变量和符号引用,还有翻译出来的直接引用,这些内容在类加载后,放倒常量池中(在运行时,JVM从常量池中获得符号引用,然后在运行时解析成引用项的实际地址,最后通过常量池中的全限定名、方法和字段描述符,把当前类或接口中的代码与其它类或接口中的代码联系起来。)
幸存区02
新生区(代)
堆
2.字段信息:字段信息存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。字段名称指的是类或接口的实例变量或类变量,字段的描述符是一个指示字段的类型的字符串,如private A a=null;则a为字段名,A为描述符,private为修饰符
到类class的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。
3.方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。(在编译的时候,就已经将方法的局部变量、操作数栈大小等确定并存放在字节码中,在装载的时候,随着类一起装入方法区。)
方法区
到类classloader的引用:到该类的类装载器的引用。
package org.fenixsoft.clazz;public class TestClass { private int m; public int inc() { return m + 1; }}全限定名:“org/fenixsoft/clazz/TestClass”是这个类的全限定名,仅仅是把类全名中的“.”替换成了“/”而已,为了使连续的多个全限定名之间不产生混淆,在使用时最后一般会加入一个“;”号表示全限定名结束。简单名称:则就是指没有类型和参数修饰的方法或者字段名称,这个类中的inc()方法和m字段的简单名称分别就是“inc”和“m”。方法和字段的描述符:描述符的作用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。比如inc方法的描述符为:()I 简单名称为: inc一个二维数组java.lang.String[][] str =new String[][]描述符为:[[java/lang/String 简单名称为:str
test
运行时数据区
对象实例数据test:name:babage:3若name没赋值或者赋值为baba1,则直接引用方法区常量池中的数据,baba1
test1
0 条评论
下一页