目录
一 数组的内存
1.1 一个数组的内存图
1.2 多个数组,指向相同的堆内存时
二 对象的内存
2.1 单个对象的内存
2.2 两个引用指向同一对象内存
三 垃圾回收机制
四 this关键字的内存图
java程序在运行时,需要在内存中分配空间,为了提高空间运算效率,就对空间进行了不同区域的划分.
每一片区域都有特定的数据处理方式 和 内存管理方式.
java中内存有5片区域
*1 栈内存:方法运行时,进入的内存,局部变量都在这里(因为局部变量在方法里面)
*2 堆内存:存放new出来的内容,并且会存在地址值,成员变量在堆内存
*3 方法区:字节码(.class)文件加载时进入的内存
4 本地方法栈:调用操作系统相关资源
5 寄存器:交给CPU去使用
方法区:.class文件加载进方法区,main方法在里面
→ 栈内存:JVM调用main方法,main方法入栈,局部变量也存放在这
→ 堆内存:通过new关键字在堆内存开辟空间,并产生地址值
→ 把 堆内存中的地址值 赋给 栈内存的局部变量
注意:每new一次在堆内存中,都是一块新的空间,堆内存中的空间地址不会出现重复的现象.
堆内存里的值变化,两个数组都变化(数组是引用数据类型)
两个数组就像下图这2个人,堆内存里的值就像被他们两同时牵着的狗,不管是哪个人给狗戴帽子和插羽毛,另一个也会同时看到狗的状态变化
有2个类时,主方法所在的测试类先加载进方法区,主方法进方法区
→ JVM调用main方法,main方法入栈,加载局部变量的Student类进入方法区,栈中存放局部变量student
→ new Student()到堆内存,产生地址值,Student类中的成员变量在堆内存中存放,Student类中的成员方法不会进入堆内存,但是会存成员方法的地址,将来可以通过堆内存中的成员方法的地址找到方法区Student类中的成员方法
→ 堆内存的student地址值赋给栈内存
当调用成员方法study()时,先通过地址值找到堆内存,再通过成员方法地址 找到方法区里的字节码文件的study()方法,找到之后把study()方法加载到栈内存中运行,开始执行study()方法里的逻辑,study()方法里的逻辑执行完毕之后,study()方法就会在栈内存中弹栈消失,主方法执行完了,也从栈内存中弹栈消失
只要2个引用指向同一块内存空间,但凡有一个对数据做了改动,另一个看到的就是改动之后的效果
stu1 = null 时,切断了指向堆内存的001地址指向路径,打印stu1.name就空指针
当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会被判定为内存中的垃圾.
垃圾会被java垃圾回收器,空闲时候自动进行清理.有些语言是需要手动清理的.
如下图,当2个引用都被切断时,堆内存里的001 就变成了垃圾