欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java程序执行内存分析(栈、堆、方法区)

程序员文章站 2024-03-22 08:32:28
...

我们结合实际程序例子来对Java程序执行的内存进行分析,以对java语言有个更深的了解

注意以下代码和实际逻辑做了一些简化,目的是能够将重点放在内存分析上,把最核心的拎出来

Computer类


public class Computer {

    public String brand;
    public String cpuSpeed;

}

Student类

public class Student {

    public String name;
    public Computer computer;

    public void goToSchool() {
        System.out.println("去学习");
    }


}

我们就来分析执行以下代码的内存状态


    public static void main(String[] args) {
        Computer c1 = new Computer();
        c1.brand="华硕";
        Student s1 = new Student();
        s1.name="张三"
        s1.computer=c1;
        Student s2 = new Student();
        s2.name="李四";
        s1.goToSchool();
    }

首先我们需要了解几个概念:

1、在内存中分为所谓的栈、堆、方法区

栈:自动分配的连续的空间,后进先出,通常用于存放局部变量

堆:不连续的空间,用于存放new出来的对象

方法区:方法区也是堆,用于存放类的信息(如代码),static变量、常量池

现在我们开始真正的内存分析:

其实本质上会先加载调用main方法的那个类,并为main方法开辟一个栈帧来执行该方法,但是我们这里为了简便就不在讲述main方法的相关内存分析

1、Computer c1 = new Computer();首先我们来看第一句代码

a、首先虚拟机会在内存中查找是否存在一个叫Computer的类,如果存在,就不用再加载,如果不存在,JVM虚拟机就会去classpath路径下,也就是项目目录下去查找并加载相关的类。类的加载机制是通过一个叫类加载器的机制来执行,类加载器的作用就是将某个类的字节码文件转化为方法区中的运行时数据结构,同时堆中生成一个代表这个类的java.lang.Class对象来作为访问方法区数据的入口。

简答点说,首先,虚拟机会让Computer这个类的class字节码文件转化为方法区的运行时数据结构,就是形成一个Computer类的模板在方法区中

那么这里为了能够更好的说明和理解java程序的运行机制,这里将加载的过程简化为在方法区中形成的运行时数据结构信息为类的代码 属性、方法、静态变量和方法、常量池

以下就是

Computer c1 = new Computer()
c1.brand="华硕";

过程的内存简单分析,注意这里尤其是运行时数据结构是不严谨的,因为真实的运行时数据结构很复杂,但是我们的基本原来是没有偏离的,所以是为了更好的理解才这么简化的,如果想要了解的话,可以深入了解一些内加载器和编译原理

这里从图中我们观察到一点就是在,在java中操作对象,本质上都是通过引用来完成的,除了一些基本累心的数据以外

Java程序执行内存分析(栈、堆、方法区)

同上理我们可以画出以下代码的内存分析图:

Student s1 = new Student();
s1.name="张三"

Java程序执行内存分析(栈、堆、方法区)

s1.computer=c1;

Java程序执行内存分析(栈、堆、方法区)

Student s2 = new Student();
        s2.name="李四";
        s1.goToSchool();

Java程序执行内存分析(栈、堆、方法区)

图片看起来虽然很凌乱,但你仔细观察,会发现其实就是各种引用,再记住那话,类是对象的模板,就可以很容易理解上图中的内存分析

相关标签: Java程序内存分析