JVM-对象内存结构

前两天去面试,和面试官聊到jvm的内存结构,因为这部分内容是比较基础的,太长时间不接触对细节总有点模糊,所以今天花了点时间总结一下。

1. jvm的内存可分为三个区域:栈(stack)、堆(heap)和方法区(method area)。

        说明:方法区也是放到堆里的,只是因为存储的内容比较特殊,所以需要单独的说明。

2. 栈

    2.1:栈是系统自动分配的一段连续的内存空间。

    2.2:栈是和线程进行绑定的,jvm会为每个线程都创建一个栈,用于存放该线程执行方法的信息,主要存储的是实际的参数和局部变量等。

    2.3:栈因为与线程进行绑定,所以是私有的,不能多个线程共享。

    2.4:栈的存储内容是后进先出(LIFO)或先进后出(FILO)的。

    2.5:栈是方法执行的内存模型,当每个方法被调用的时候都会创建一个栈帧,而栈帧里会存储局部变量、操作数和方法的出口等。

JVM-对象内存结构_第1张图片

3. 堆

    3.1:存储创建好的对象。

    3.2:jvm只有一个堆,所有线程共享。

    3.3:不连续的空间。

4. 方法区(静态区)

    4.1:jvm只有个方法区,所有线程共享。

    4.2:方法区是堆的一部分,只是用来存储类和常量相关的信息。用来存放程序中不变或唯一的内容。比如,类的信息,静态变量和字符常量等。

5. 简单的对象内存结构分析

先上代码:

public class Person {

    int id;
    String name;
    int age;
    
    void study() {
        System.out.println("学习");
    }
    
    void play() {
        System.out.println("玩游戏");
    }
    
    public static void main(String[] args) {
        Person p = new Person();
        p.id = 1;
        p.name = "唐僧";
        p.age = 18;
        
        p.play();
        p.study();
    }
 }

代码很简单,主要是用这段代码分析下它在内存里的结构。

再上图:JVM-对象内存结构_第2张图片

下面解释下,

    5.1:当jvm在启动的时候会进行类的装载,这个时候会把person这个类的代码信息装载到方法区里,也会把类里面的一些静态的方法变量和常量都装载到方法区里。(这个时候没有栈,在堆里也没有person的实例对象,只有方法区)

    5.2:创建线程,创建与线程绑定的栈。

    5.3:运行main方法(这个main方法的信息也是保存在方法区的),这个时候会在栈里面创建一个main方法的栈帧(15db9742为对象在内存里的地址),这个时候对象里的属性都是默认值(注意,这里Person的构造方法执行完后对应的栈帧也会被移除掉)。然后把p执行这个新创建的实例化对象的地址。

    5.4:15db9742这个对象的属性赋值操作,基本数据类型是修改属性的值,而String类型是把成员变量指向了方法区里的常量。

    5.4:main方法运行 执行Person p = new Person();这行代码的时候,会现在main方法的栈帧里创建一个p,此时为null。然后调用Person的构造方法,这个时候会在栈里创建Person的构造方法的栈帧,这个栈帧执行完后会在堆里创建一个Person的实例对象

    5.5:代码继续执行到方法play和study。执行方法的时候进行数据打印输出,操作的时候内存里会从方法区的常量里进行寻找需要输出的内容。

 

结束。

 

转载于:https://my.oschina.net/u/128964/blog/1838218

你可能感兴趣的:(JVM-对象内存结构)