JVM内存管理机制

JVM内存管理机制_第1张图片
image.png

Java堆

Java堆是被所有线程共享的一块内存区域,主要用于存放对象实例,Java虚拟机规范中有这样一段描述:所有的对象实例和数据都要在堆上进行分配。

Java栈

Java栈是线程私有的,每个线程对应一个Java栈,每个线程在执行一个方法时会创建一个对应的栈帧(Stack Frame),栈帧负责存储局部变量变量表、操作数栈、动态链接和方法返回地址等信息。每个方法的调用过程,相当于栈帧在Java栈的入栈和出栈过程。
局部变量表 用于存放方法参数和方法内部定义的局部变量,其大小在代码编译期间已经确定,在方法运行期间不会改变

方法区

方法区和Java堆一样,是所有线程共享的内存区域,用于存放已被虚拟机加载的类信息、常量、静态变量和即时编译器编译后的代码等数据。只有一份
运行时常量池是方法区的一部分,用于存放编译期间生成的各种字面常量和符号引用

堆中的数据是线程共享,在没有引用时,被GC回收
栈中的数据是线程独享,从方法调用开始开辟栈桢,到方法调用结束栈桢清除,局部变量消失。

Java对象所占用的内存主要在堆上实现,因为堆是线程共享的,因此在堆上分配内存时需要进行加锁,这就导致了创建对象的开销比较大。当堆上空间不足时,会出发GC,如果GC后空间仍然不足,则会抛出OutOfMemory异常

ps:

成员变量:

1、静态变量
2、实例变量:定义在类中,方法外,有默认值,存于堆中,生命周期从创建开始到回收结束。

局部变量:定义在方法中,需手动初始化,存于栈中,声明周期从方法调用到方法结束。
public class JavaTest {
    private int a = 0;  //基本类型,栈中
    private String name = new String("test");//实例在堆中,引用在栈中
    public static int b = 5;//方法区
    
    public static void main(String[] args) throws MalformedURLException {
        int c = 123;//局部变量,基础数据类型,都在栈的局部变量表里,线程独享
        String interest = "food";//局部变量,引用类型,引用在栈的局部变量表里,实例在堆中,线程独享
        JavaTest test = new JavaTest();//实例在堆中,引用在栈中,线程独享
    }
    
}

你可能感兴趣的:(JVM内存管理机制)