java内存分配、java垃圾回收机制

102 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一 java内存分配

java程序在运行时,需要在内存中分配空间,为了提高空间运算效率,就对空间进行了不同区域的划分.

每一片区域都有特定的数据处理方式 和 内存管理方式.

java中内存有5片区域

1 栈内存:方法运行时,进入的内存,局部变量都在这里(因为局部变量在方法里面)
2 堆内存:存放new出来的内容, 并且会存在地址值,成员变量在堆内存
3 方法区:字节码(.class)文件加载时进入的内存
4 本地方法栈:调用操作系统相关资源
5 寄存器:交给CPU去使用

1 数组的内存

1.1 一个数组的内存图

1 方法区:.class文件加载进方法区,main方法在里面 
2 栈内存:JVM调用main方法,main方法入栈,局部变量也存放在这
3 堆内存:通过new关键字在堆内存开辟空间,并产生地址值
4 把 堆内存中的地址值 赋给 栈内存的局部变量

 注意:每new一次在堆内存中,都是一块新的空间,堆内存中的空间地址不会出现重复的现象.

1.2 多个数组,指向相同的堆内存时

堆内存里的值变化,两个数组都变化(数组是引用数据类型)

两个数组就像下图这2个人,堆内存里的值就像被他们两同时牵着的狗,不管是哪个人给狗戴帽子和插羽毛,另一个也会同时看到狗的状态变化

2 对象的内存

2.1 单个对象的内存

image.png

1 有2个类时,主方法所在的测试类先加载进方法区,主方法进方法区

2 JVM调用main方法,main方法入栈,加载局部变量的Student类进入方法区,栈中存放局部变量student

3 new Student()到堆内存,产生地址值,Student类中的成员变量在堆内存中存放,Student类中的成员方法不会进入堆内存,但是会存成员方法的地址,将来可以通过堆内存中的成员方法的地址找到方法区Student类中的成员方法

4 堆内存的student地址值赋给栈内存

5 当调用成员方法study()时,先通过地址值找到堆内存,再通过成员方法地址 找到方法区里的字节码文件的study()方法,找到之后把study()方法加载到栈内存中运行,开始执行study()方法里的逻辑,study()方法里的逻辑执行完毕之后,study()方法就会在栈内存中弹栈消失,主方法执行完了,也从栈内存中弹栈消失

 

2.2 两个引用指向同一对象内存

只要2个引用指向同一块内存空间,但凡有一个对数据做了改动,另一个看到的就是改动之后的效果

1.png  stu1 = null 时,切断了指向堆内存的001地址指向路径,打印stu1.name就空指针

2.png

3 this关键字的内存图

二 垃圾回收机制

  • 当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会被判定为内存中的垃圾.

  • 垃圾会被java垃圾回收器,空闲时候自动进行清理.有些语言是需要手动清理的.

  • 如下图,当2个引用都被切断时,堆内存里的001 就变成了垃圾