JVM内存管理机制

5540038-71cd5d56562913aa.png
image.png

Java堆

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

Java栈

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

方法区

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

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

Java对象所占用的内存主要在堆上实现,由于堆是线程共享的,所以在堆上分配内存时须要进行加锁,这就致使了建立对象的开销比较大。当堆上空间不足时,会出发GC,若是GC后空间仍然不足,则会抛出OutOfMemory异常对象

ps:blog

成员变量:

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

局部变量:定义在方法中,需手动初始化,存于栈中,声明周期从方法调用到方法结束。
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();//实例在堆中,引用在栈中,线程独享
    }
    
}