JVM各个区域
1.堆
成员变量(成员变量作为对象的属性,当然是放在堆里了。对象在堆里,对象中的内容就是各种字段)
各种对象
字符串常量池(⽤于存放编译期⽣成的各种字⾯量和符号引⽤,这个以前在运行时常量池内)
2.方法区
加载的类信息(Class实例)、常量、静态变量
运行时常量池:常量池是方法区中的一部分,主要用来存放常量和类中的符号引用等信息
3.程序计数器
记录虚拟机字节码指令的地址,为了线程切换后恢复到正确的执行位置(唯一一个没有OOM的区域,生命周期随着线程的创建而创建,死亡而死亡)
读取指令,实现代码流程控制,比如顺序执行、选择、循环、异常处理
4.虚拟机栈
栈帧(局部变量、操作数、动态链接、方法出口)、对象的引用,每一次方法调用都会有一个对应的栈帧被压入虚拟机栈,每次方法结束,相应栈帧都会弹出
局部变量
基本数据类型:引用、值直接存储在栈上
引用类型:String s=new String("william"),会把其对象存储在堆,把这个对象的引用指针存储在栈
5.本地方法栈
与虚拟机栈发挥的作用十分相似,区别是虚拟机栈执行Java方法(字节码)服务,本地方法栈为虚拟机执行Native方法服务在本地⽅法栈也会创建⼀个栈帧,⽤于存放该本地⽅法的局部变量表、操作数栈、动态链接、出⼝信息
局部变量表
堆、栈区别
1.栈:用来存储栈帧、对象引用
堆:存储Java对象,成员变量、类变量
2.栈:线程私有
堆:线程共有
3.栈:栈空间不足抛java.lang.StackOverFlowError
堆:堆空间不足抛java.lang.OutOfMemoryError
4.栈空间远远小于堆空间
堆内存中对象的分配的基本策略
- 对象优先分配在eden区
- 大对象直接进入老年代,比如:字符串、数组,避免之后采用复制算法降低效率
- 分代年龄到达15的对象进入老年代,每经过一次MinorGC,年龄+1