我们的数据都是存放在内存中,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类图如下:
内存分配图如下:
反编译内容如下:
// 反编译命令 : 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"