初识Java内存结构

我们的数据都是存放在内存中,Java内存大体可以分为寄存器、堆、栈、方法区、常量池。
程序=数据结构+算法,数据结构存在堆中,算法存在方法区中。

1、堆 heep


  • 堆用于存储创建好的对象和数组(数组也是对象);
  • JVM只有一个堆,被所有线程共享;
  • 自动回收垃圾;
  • 是一个不连续的内存空间,分配灵活,存取速度较慢;

2、方法区 method area


  • JVM只有一个方法区,被所有线程共享!
  • 方法区实际也是堆,只是用于存储类、常量相关的信息!
  • 用来存放程序中永远是不变或唯一的内容。(如 类信息【Class对象】、静态变量、字符串常量等)

3、栈 stack


  • 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等);
  • JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等);
  • 栈属于线程私有,不能实现线程间的共享!
  • 栈的存储特性是“先进后出,后进先出”;
  • 栈是由系统自动分配,速度快!栈是一个连续的内存空间!

4、寄存器 registers


  • 程序计数寄存器:跟踪程序执行的准确性;
  • 堆栈指针寄存器:指示操作栈顶;
  • 框架寄存器:指向当前执行的环境;
  • 变量寄存器:指向当前执行环境中第一个本地变量;

5、常量池 constant pool


  • 用来存储某类型的常量信息;
  • 存储较小的数值;
  • 存储源文件中的字面量(文本字符串、被声明为final的常量值、基本数据类型的值等);
  • 提高存储效率;

6、本地方法栈 nativemethodstack


  • 保存调用本地方法的地址;

【示例】Java内存分配分析

示例代码如下:

class Computer {
    // 品牌
    String brand;
}

public class Student {
	// 属性
    int id;
    String name;
    int age;
    Computer comp;
	
    // 方法
    void study() {
        System.out.println("我正在学习!使用我们的电脑:" + comp.brand);
    }

    public static void main(String[] args) {
        Student student = new Student();
        student.name = "白豆五";
        Computer computer = new Computer();
        computer.brand = "拯救者Y7000";
        student.comp = computer;
        student.study();
    }
}

UML类图如下:
image

内存分配图如下:
image

反编译内容如下:

// 反编译命令 : javap -v Class文件
D:\Users\WorkSpace\Java\算法\ArraysDemo\out\production\ArraysDemo\com\baidou\hello>javap -v Student.class

Classfile /D:/Users/WorkSpace/Java/算法/ArraysDemo/out/production/ArraysDemo/com/baidou/hello/Student.class
  Last modified 2022-1-6; size 1156 bytes
  MD5 checksum faf4c49627d987c6f35393b6998953bd
  Compiled from "Student.java"
public class com.baidou.hello.Student
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
// 常量池
Constant pool:
   #1 = Methodref          #19.#43        // java/lang/Object."<init>":()V
   #2 = Fieldref           #44.#45        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = Class              #46            // java/lang/StringBuilder
   #4 = Methodref          #3.#43         // java/lang/StringBuilder."<init>":()V
   #5 = String             #47            // 我正在学习!使用我们的电脑:
   #6 = Methodref          #3.#48         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #7 = Fieldref           #11.#49        // com/baidou/hello/Student.comp:Lcom/baidou/hello/Computer;
   #8 = Fieldref           #15.#50        // com/baidou/hello/Computer.brand:Ljava/lang/String;
   #9 = Methodref          #3.#51         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #10 = Methodref          #52.#53        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #11 = Class              #54            // com/baidou/hello/Student
  #12 = Methodref          #11.#43        // com/baidou/hello/Student."<init>":()V
  #13 = String             #55            // 白豆五
  #14 = Fieldref           #11.#56        // com/baidou/hello/Student.name:Ljava/lang/String;
  #15 = Class              #57            // com/baidou/hello/Computer
  #16 = Methodref          #15.#43        // com/baidou/hello/Computer."<init>":()V
  #17 = String             #58            // 拯救者Y7000
  #18 = Methodref          #11.#59        // com/baidou/hello/Student.study:()V
  #19 = Class              #60            // java/lang/Object
  #20 = Utf8               id
  #21 = Utf8               I
  #22 = Utf8               name
  #23 = Utf8               Ljava/lang/String;
  #24 = Utf8               age
  #25 = Utf8               comp
  #26 = Utf8               Lcom/baidou/hello/Computer;
  #27 = Utf8               <init>
  #28 = Utf8               ()V
  #29 = Utf8               Code
  #30 = Utf8               LineNumberTable
  #31 = Utf8               LocalVariableTable
  #32 = Utf8               this
  #33 = Utf8               Lcom/baidou/hello/Student;
  #34 = Utf8               study
  #35 = Utf8               main
  #36 = Utf8               ([Ljava/lang/String;)V
  #37 = Utf8               args
  #38 = Utf8               [Ljava/lang/String;
  #39 = Utf8               student
  #40 = Utf8               computer
  #41 = Utf8               SourceFile
  #42 = Utf8               Student.java
  #43 = NameAndType        #27:#28        // "<init>":()V
  #44 = Class              #61            // java/lang/System
  #45 = NameAndType        #62:#63        // out:Ljava/io/PrintStream;
  #46 = Utf8               java/lang/StringBuilder
  #47 = Utf8               我正在学习!使用我们的电脑:
  #48 = NameAndType        #64:#65        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #49 = NameAndType        #25:#26        // comp:Lcom/baidou/hello/Computer;
  #50 = NameAndType        #66:#23        // brand:Ljava/lang/String;
  #51 = NameAndType        #67:#68        // toString:()Ljava/lang/String;
  #52 = Class              #69            // java/io/PrintStream
  #53 = NameAndType        #70:#71        // println:(Ljava/lang/String;)V
  #54 = Utf8               com/baidou/hello/Student
  #55 = Utf8               白豆五
  #56 = NameAndType        #22:#23        // name:Ljava/lang/String;
  #57 = Utf8               com/baidou/hello/Computer
  #58 = Utf8               拯救者Y7000
  #59 = NameAndType        #34:#28        // study:()V
  #60 = Utf8               java/lang/Object
  #61 = Utf8               java/lang/System
  #62 = Utf8               out
  #63 = Utf8               Ljava/io/PrintStream;
  #64 = Utf8               append
  #65 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #66 = Utf8               brand
  #67 = Utf8               toString
  #68 = Utf8               ()Ljava/lang/String;
  #69 = Utf8               java/io/PrintStream
  #70 = Utf8               println
  #71 = Utf8               (Ljava/lang/String;)V
{
  int id;
    descriptor: I
    flags:

  java.lang.String name;
    descriptor: Ljava/lang/String;
    flags:

  int age;
    descriptor: I
    flags:

  com.baidou.hello.Computer comp;
    descriptor: Lcom/baidou/hello/Computer;
    flags:

  public com.baidou.hello.Student();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 9: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/baidou/hello/Student;

  void study();
    descriptor: ()V
    flags:
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: new           #3                  // class java/lang/StringBuilder
         6: dup
         7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
        10: ldc           #5                  // String 我正在学习!使用我们的电脑:
        12: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        15: aload_0
        16: getfield      #7                  // Field comp:Lcom/baidou/hello/Computer;
        19: getfield      #8                  // Field com/baidou/hello/Computer.brand:Ljava/lang/String;
        22: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        25: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        28: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        31: return
      LineNumberTable:
        line 16: 0
        line 17: 31
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      32     0  this   Lcom/baidou/hello/Student;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: new           #11                 // class com/baidou/hello/Student
         3: dup
         4: invokespecial #12                 // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: ldc           #13                 // String 白豆五
        11: putfield      #14                 // Field name:Ljava/lang/String;
        14: new           #15                 // class com/baidou/hello/Computer
        17: dup
        18: invokespecial #16                 // Method com/baidou/hello/Computer."<init>":()V
        21: astore_2
        22: aload_2
        23: ldc           #17                 // String 拯救者Y7000
        25: putfield      #8                  // Field com/baidou/hello/Computer.brand:Ljava/lang/String;
        28: aload_1
        29: aload_2
        30: putfield      #7                  // Field comp:Lcom/baidou/hello/Computer;
        33: aload_1
        34: invokevirtual #18                 // Method study:()V
        37: return
      LineNumberTable:
        line 20: 0
        line 21: 8
        line 22: 14
        line 23: 22
        line 24: 28
        line 25: 33
        line 26: 37
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      38     0  args   [Ljava/lang/String;
            8      30     1 student   Lcom/baidou/hello/Student;
           22      16     2 computer   Lcom/baidou/hello/Computer;
}
SourceFile: "Student.java"

人生最难做到的就是坚持,最容易的就是放弃。

原文地址:https://www.cnblogs.com/m987/p/15772555.html