JAVA 垃圾回收
1. 何为“垃圾”?
- 个人理解,”垃圾“ 指的是 程序在运行过程中 ”死亡对象“ 所占用的空间。
- “死亡对象” 具体来说就是 运行过程中申请的内存空间不再使用,它不仅仅是面向对象编程的相关概念,比如,用 C 申请了一段内存实现某个功能,但这段内存后续不再使用,这段内存也称之为 ”垃圾“。不需要在应用程序中显示管理内存也是 JAVA 流行的一大原因吧。
- 如何判断 ”对象“ 已经死亡有许多不同的方法,可以根据自己的应用场景采用不同的方法。
2. 为什么要回收垃圾?
理解了何为”垃圾“,谈一谈为何需要垃圾回收。
声明:下列用词不涉及进程、线程、协程的讨论争辩,只是单纯的称之为进程,具体语言操作系统实现方式有所不同。
程序装载到内存中称为进程,进程结束,它所持有的资源也被释放。让操作系统自动回收进程所占用的资源不就可以了吗?为何还需要去实现一个垃圾回收器对进程进行干预呢,垃圾回收器本身也是一个进程呀,不是增大了开销吗?
- 因为现实场景中,服务提供方的 服务进程大多都是以常驻进程(即进程一直在内存中保持运行态)的形式存在,内存是稀缺资源,若存在大量的内存空间不再使用,但却又无法复用,这是一种资源的浪费(这种现象也称为内存泄漏)。极端情况下,内存耗尽,进程无法继续运行,无法为用户提供服务。
- 垃圾回收器的存在确实会对性能产生影响,任何事情都是需要经过 trade-off(平衡)的,如何选择适合引用的垃圾回收器也是要通过不断实践去论证。
垃圾回收 对于进程来说就是让这些不再使用的内存空间得以复用,提高内存利用率 。
3. 常见的垃圾收集算法
3.1 标记-清除算法
3.2 标记-整理算法
3.3 复制算法
4. 何时触发垃圾回收?
这个不同的垃圾回收器实现方式不一样,何时触发垃圾回收也和 JAVA内存模型—堆 相关,笔者觉得知道垃圾回收是 ”stop the world(stw)“ 还是 并发的 比较重要,其实对于单核来说,垃圾回收器并发其实也就是 stw。
这方面的学问比较深,感兴趣的可以仔细专研。
5. 查看项目使用的垃圾收集器
1. 测试的 JDK 版本
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
2. 查看 java 使用的垃圾收集器代码
public static void main(String[] args) {
List<GarbageCollectorMXBean> beans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean bean : beans) {
System.out.println(bean.getName());
}
}
3. 运行结果
PS Scavenge
PS MarkSweep
Process finished with exit code 0
上述两种垃圾收集器信息如下:
推荐的垃圾回收器组合
ParNew/CMS 组合配置,原因见 😅链接找不见了,见谅。