内存分析内存分析(未完成)

Posted syxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存分析内存分析(未完成)相关的知识,希望对你有一定的参考价值。

栈的特点如下:

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)

  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

  3. 栈属于线程私有,不能实现线程间的共享!

  4. 栈的存储特性是“先进后出,后进先出”

  5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

堆的特点如下:

  1. 堆用于存储创建好的对象和数组(数组也是对象)

  2. JVM只有一个堆,被所有线程共享

  3. 堆是一个不连续的内存空间,分配灵活,速度慢!

方法区(又叫静态区)特点如下:

  1. JVM只有一个方法区,被所有线程共享!

  2. 方法区实际也是堆,只是用于存储类、常量相关的信息!

  3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)

来源:速学堂 4.4 面向对象的内存分析

技术分享图片

了解栈、堆和方法区的特点后,我们来对以下代码进行内存分析

public class Student {
    //属性(成员变量) field s
    int id;
    String name;
    int age;
    
    Computer comp;
    
    //方法
    void study(){
        System.out.println("我在学习");
    }
    void play() {
        System.out.println("我在玩碧蓝航线!用笔记本"+comp.brand);
    }
    
    Student (){
        //构造方法。用于创建这个类的对象,无参的构造方法可以由系统自动生成
    }
    
    public static void main(String[] args) {
        Student stu = new Student();//通过Student类的构造函数Student()方法新建一个stu对象
        stu.age=19;
        stu.id=19;
        stu.name="水音";
        
        Computer c1 = new Computer();
        c1.brand = "神舟";
        stu.comp = c1;
        
        stu.play();
        stu.study();
    }
    
}

class Computer{
    String brand;
}

让我们回到万物的起点

javac Student.java 和 java Student

技术分享图片

javac 是将 .java 文件编译成 JVM(java虚拟机)能够读懂的 .class java字节码文件

java 则是执行字节码文件,我们从这里开始分析

 在调用 java 的时候,启动虚拟机,内存空间如下图所示

技术分享图片

接着是执行 Student 类,执行这个类之前需要找到这个类,首先需要把 Student 类加载到内存空间里面

接着在方法区里面,就有了这个类的信息

技术分享图片

有了这些信息后,相当于 java Student 这条命令执行完了

接着就开始寻找 main 方法,main 方法是程序执行的入口

在调用 main 方法的时候就会在栈中开辟一个栈帧

技术分享图片

main 方法

public static void main(String[] args) {
        Student stu = new Student();//通过Student类的构造函数Student()方法新建一个stu对象
        stu.age=19;
        stu.id=19;
        stu.name="水音";
        
        Computer c1 = new Computer();
        c1.brand = "神舟";
        stu.comp = c1;
        
        stu.play();
        stu.study();
    }

main 方法首先定义了一个 Student 类型的引用变量 stu ,目前它的值为空(null

技术分享图片

接着 new 了一个对象,根据 Student 类的构造器(构造方法),所以在栈中开辟一个新的栈帧

技术分享图片

开辟完后开始执行这个方法,依据构造器初始化这个类,生成这个类的对象

执行完后获得对象 ,栈帧弹出

技术分享图片

接着将这个新建好的对象给 stu 

也就是把 stu 的地址指向新建好的对象的地址 

通过地址值将它们关联起来

Tip:不用在意 1e6d1014 这个地址是怎么来的,只是随便打的

技术分享图片

 

 接着执行 stu.age 

    public static void main(String[] args) {
        Student stu = new Student();//通过Student类的构造函数Student()方法新建一个stu对象
        stu.age=19;
        stu.id=19;
        stu.name="水音";
        
        Computer c1 = new Computer();
        c1.brand = "神舟";
        stu.comp = c1;
        
        stu.play();
        stu.study();
    }

mian 方法里执行,所以在 main 方法的栈帧里面找 stu 对象,根据 stu 的地址找到 age

并将 age 赋值为 19 

技术分享图片

id 的赋值同上

技术分享图片

需要注意的是 name 的赋值

找到 name 以后,会在方法区里找到 水音 这个字符串常量并将 name 的地址指向它


以上是关于内存分析内存分析(未完成)的主要内容,如果未能解决你的问题,请参考以下文章

一个未完成的2.6.32-220内核踩内存crash分析记录

方法与对象内存分析

变量的内存分析图

Android内存泄漏分析实战

引发C++程序内存错误的常见原因分析与总结

如何检测在 Netbeans 中进行分析时未显示的内存泄漏? [关闭]