文章目录
前言:java程序经过编译器编译由.java生成.class字节码文件,部署到不同的可执行平台后,jvm虚拟机通过解析.class文件来执行代码,在编译过程中,为防止class字节码过大,大致会把.class文件分为两大部分,在每个.class字节码文件中存放一个常量池
1. class常量池
class常量池中包含如下内容:
1、文本字符串
2、八种基本数据类型值
3、final变量
4、类名称、包名、类修饰符
5、方法名称、方法修饰符
2. jvm虚拟机内存大致划分
jvm虚拟机大致包含:
1、方法区
2、堆heap
3、栈stack
2.1 方法区
方法区包含如下内容:
1、类名称、父类名称、包名、类修饰符、类接口结构表
2、属性名称、属性类型、属性修饰符、属性顺序
3、方法名称、方法返回值类型、方法参数数量、方法参数类型、方法参数顺序、方法修饰符、方法字节码、方法代码执行步骤、方法局部变量表
2.2 堆heap
堆包含如下内容:
1、引用类型对象本身
2、字符串常量池
3、运行时常量池
2.3 栈stack
1、存放基本数据类型值
2、存放对象引用地址
3、存放属性引用地址
4、存放引用类型、具体的名称
外音:
- 逻辑上,jvm虚拟机在解析执行.class文件时,会将class文件常量池的内容加载到内存中方法区的里面,文本字符串加载到字符串常量池,其他数据加载到运行时常量池
- 实际存储时,字符串常量池和运行时常量池均存储于堆heap中
3. java字符串常量池存在目的
因为java底层核心的反射层返回的都是字符串,为了保证不出错,所以字符串都是final的常量,单独有一个字符串常量池存放
3.1 字符串常量池产生流程
java每次创建字符串都会在池子中创建,然后把引用指过来
4. 堆栈、常量池、对象、引用之间关系
String s1 = "abc";
这个有两个动作,一个是在堆的字符串常量池创建一个abc的字符串,另一个动作就是在栈中创建一个s1指向abc
String s2=new String("abc");
这个是三个动作,首先在堆中字符串常量池创建abc,然后在堆中创建new String对象,最后在栈中创建s2引用,s2指向的是String对象,String对象中有abc这个字符串常量
总结
说白了java中堆存放对象和字符串常量池,由GC负责管理生命周期,栈存放引用,程序作用域决定了引用生命周期