java内存模型
线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享(公有):堆、方法区
堆内存:
堆内存分为新生代和老年代,年轻代和老年代默认的比例是1:3,其中年轻代又分为Eden和Survivor区,Survivor区包含s0和s1区,Eden、s0和s1区在年轻代的默认占比是8:1:1。
堆内存中存放的是对象信息。
程序在运行过程中会不断的创建对象,生成的对象会存放在eden区,eden区内存满了之后,会进行minor gc,然后将存活的对象移动到s0区,s0区满了之后,会重新进行minor gc,然后将存活的对象移动到s1,反复进行此操作,在minor gc过程中,会将存活大于15的对象移动到老年代。年轻代在gc过程中,由于内存不够,存放的大对象会直接移动到老年代。老年代内存满了之后会进行full gc,进行full gc的过程中,年轻代也会进行minor gc。
虚拟机栈:
每一个线程的启动都会在虚拟机栈中获取到一块独立的空间,虚拟机栈中又包含了栈帧和程序计数器,每一个方法对应一个栈帧。栈帧中包含了局部变量表、操作数栈、动态连接、方法出口,每一个栈帧中都存在这些信息。虚拟机栈会进行First In, Last Out(先进后出),代码在执行过程中会从栈顶开始执行,最先进入栈内的信息会最后执行。
- 程序计数器:每个线程独有的。存储的代码指定当前行的行号。
- 栈帧:一个方法对应一个栈帧。
–<栈帧内部>
- 局部变量表:方法中的变量。
- 操作数栈:线程执行过程中,在操作数栈中对变量赋值操作,赋值完成之后移动到局部变量表中。可以理解为临时存放运算的一块空间。
- 动态连接:每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。可以理解为方法中引用到别的方法。
- 方法出口:存放的返回主方法的信息,比如执行完栈顶的栈帧,返回下一个栈帧的信息。
本地方法栈:由c编写的的本地方法,给本地方法提供的一块空间。
方法区(元空间):存放类中的常量,静态变量,类信息等。
代码示例
代码区
public class Math {
public static int initData=666;
public static User user= new User();
public int compute(){
int a=1;
int b=2;
int c=(a+b)*10;
return c;
}
public void getUser(){
User user = new User();
user.setUuid