likes
comments
collection
share

用饭店趣味类比 Java 的垃圾回收机制

作者站长头像
站长
· 阅读数 3

因为在B站尚学堂的高淇老师的一期视频中,我初步了解了Java里的垃圾回收机制。 为了巩固所学,再这里输出一遍,以检验自己的吸收程度。

程序要运行,就要在内存中开辟空间,然后再释放。C++中,这个释放的动作是由程序员👨🏻‍💻自己手动来做的。而 Java 和 Python 则都是自动去回收的。

要回收,首先得知道空间大部分被谁给占用了。其实大部分就是被堆中的对象占用了。堆中的对象是什么时候被创建的呢?就是在程序里出现 Object name = new Object(); 这样的代码时,才去分配内存空间。

垃圾回收(Garbage Collection) 包括两个部分:

  1. 发现垃圾: 找到要回收的对象,没有被任何变量引用;
  2. 回收垃圾: 把引用变量都赋值为 null。

找到垃圾的算法有两种:

  1. 引用计数法: 通过计数来确认对象的被引用次数是否为 0 ;
  2. 引用不可达法: 引用图的概念,有引用关系就会有“点——点”这种关系,那么单独一个节点就是“不可达的”。

要注意:

  1. 我们是不用去调垃圾回收的;
  2. System.gc(),只能提建议,虽然一般都会被执行但还是别乱捣乱,因为执行一次就是启动了 full GC,成本比较高、费性能;
  3. finalize 方法是用来释放对象或资源的方法,但是尽量少用。

有个生动的故事类比,很容易记忆 Java 里的分代机制。 有三个状态区,分别类比到带大堂的饭店里的区域:

  • 年轻代,Eden + Survivor1、Survivor2(这三个词代表三块空间) ——快餐区,来了刚进门,就在 Eden区,买了拎着餐盒就走,着急回工位去吃饭那就直接走人,如果站的人 4、5 个站满了,立马就有一个叫 Minor GC 的清洁阿姨来请他们走。

还有没完事的,就要请他去隔壁的 Survivor1、Survivor2桌子坐一下,在这两个 S words里循环,超过 15次后,那么就对不起,你不再年轻了;

  • 年老代,Tenured ——包间,坐着慢慢吃,那就去坐里面慢慢吃,超过 15次了,没办法,这时候服务员要清的话,就要升级咯,要由 Major GC来专门清理。Full GC 就像清洁经理,一发令就是启动是可以同时清掉 年老代和年轻代的对象;

  • 永久代 ——永久存储的,程序在就在,直到关闭才没有,主要放静态变量、类信息(方法区)。