Java内存图介绍
- 栈
- 堆
- 方法区
- 本地方法栈
- 寄存器
如下图所示(jdk8之前): 如下图所示(jdk8之后):
jdk8之后将方法区取消,新增元空间,把原来方法区功能进行拆分,一部分分给元空间,另一部分则是给了堆
方法区:字节码文件加载时进入的内存
栈内存:方法运行时进入的内存,变量也在此处
堆内存:new出来的东西会放在这块内存中,开辟空间并产生地址
当我们创建一个对象时,例如:
Student s =new Student();内存至少进行七件事:
现结合具体实例分析:
创建一个学生类:
创建一个测试类:
内存运行如下:
- 方法区加载字节码文件TestStudent.class,并且临时存储main()方法,此时虚拟机调用main方法,将main方法加载至栈中
- 接着执行main方法中代码,Student s =new Student(); 分为七步:
1)加载Student.class文件至方法区中,
2)Student s,在main方法中开辟空间,该空间可存储Student类对象的地址值,
3)new Student(),开辟空间001,放入成员变量,以及成员方法地址
4)默认初始化值
5)显示初始化指 如果成员变量有初始值,将初始值覆盖 null 0
6) new Student()由于是空参构造,因此此步忽略
7)将堆内存中的值赋给栈中main方法的局部变量
3.程序往下执行,此时直接sout(s)相当于直接输出一个地址001,因为在main方法中s所存储的是一个地址空间。若此时输出s.name s.age 则是输出001地址中的name 和 age值,同理s.name="阿强"也是如此,把小强赋值给001地址中的name。
4.接着执行s.study(),过程类似,首先找到s的地址001,在001中找到study()方法的地址,然后在按照地址在方法区中找到方法,此时study()方法加载入栈,执行该方法,此时代码全部执行完毕,依次出栈,栈空,由于占内存已经空,无人指向堆内存,因此堆内存释放。完毕!