本文讨论了有关 Java 垃圾收集(GC)的知识,该垃圾收集被视为 Java 编程语言中的复杂主题之一。
顾名思义,java 中的垃圾收集功能可以自动从内存中搜索,发现和删除垃圾,而无需用户明确执行此工作。 这里的垃圾是指未引用的对象。
有多种方法可以使对象成为未引用和无用的对象。 一些是:
- 引用的清零
- 将引用分配给另一个
- 匿名对象等等
因此,垃圾收集功能会找出这些对象并自动将其从内存中删除并删除它们,从而实现高效的内存使用和管理。
如果要用 C 语言进行相同的垃圾收集和优化,则可以使用free()
函数,而在 C++ 中,则可以使用delete()
方法。 因此,Java 中此过程实现了自动化,从而为用户减少了麻烦。
从技术上讲,Java 垃圾收集处理的是跟踪 JVM(Java 虚拟机)堆空间中的每个对象,并删除(删除/取消分配)未使用的对象。
垃圾收集(GC)实现有 4 种类型:
- 串行垃圾收集器
- 并行垃圾收集器
- CMS 垃圾收集器
- G1 垃圾收集器
串行垃圾收集器
GC 的此实现仅使用一个线程,并且在运行时冻结所有应用程序线程。 因此,它不是在多线程应用程序中使用的最佳选择。 所有垃圾收集事件都在一个线程中串行进行。
它用于对暂停时间要求不高且在客户端样式的计算机上运行的应用程序中。 它是为单线程系统设计的,是 JVM 中较小堆大小的首选。
并行垃圾收集器
此变体是 JVM 的默认垃圾收集器,也称为吞吐量收集器。 并行 GC 在管理堆时利用多个线程,而串行 GC 则不然。 但是,像串行 GC 一样,它在运行时也会冻结其余的应用程序线程。
可以指定最大垃圾收集线程以及暂停时间,吞吐量和占用空间(堆大小)。
CMS 垃圾收集器
CMS 代表并发标记扫描,并同时使用多个 GC 线程来扫描堆并标记未引用的对象,这些对象随后在扫描中被删除/取消分配。 对于那些需要短时间垃圾收集暂停并能够负担与 GC 共享资源的应用程序,它是首选。 使用该 GC 实现的应用程序比不使用 GC 的应用程序要慢,但是在执行垃圾收集时它们不会完全暂停整个应用程序。
在两种情况下,垃圾收集器的这种含义进入了“世界停止”(STW)模式:
- 在初始化根的初始标记时
- 当算法同时运行时,应用程序更改了堆的状态时; 强制其返回以确保标记了正确的对象。
当对象从年轻一代移动到老一代并且收集器没有足够的时间在老一代中腾出空间时,会遇到升级失败。
G1 垃圾收集器
G1 代表垃圾优先 GC,适用于在具有大内存的多处理器计算机上运行的应用程序。 与 CMS 收集器相比,它具有更高的性能效率。
G1 GC 将堆划分为一组大小相等的堆区域,并标记并发的全局标记阶段,以确定是否正在使用堆中的对象。
标记完成后,GC 知道哪些区域大部分为空。 然后,GC 首先从这些区域收集垃圾(这称为清扫阶段),从而产生大量可用空间。 因此,该名称首先是垃圾。
垃圾收集的好处:
- 没有手动的内存分配/取消分配处理,因为 GC 会自动处理未使用的内存空间
- 没有处理悬空指针的开销
- 自动内存泄漏管理
垃圾收集的缺点:
- 跟踪对象引用的创建/删除需要更多的 CPU 能力,并且可能会影响需要大内存的请求的性能
- 程序员无法控制专用于释放不再需要的对象的 CPU 时间的调度
- 使用某些 GC 实现可能会导致应用程序意外停止
- 在某些情况下,自动内存管理可能不如适当的手动内存分配/取消分配那样有效。
一个简单的程序,显示 Java 垃圾收集的实现:
public class TryingGrabageCollection{
public void finalize(){
System.out.println("Object has been collected by the garbage collector!");
}
public static void main(String args[]){
TryingGrabageCollection obj1 = new TryingGrabageCollection ();
TryingGrabageCollection obj2 = new TryingGrabageCollection ();
obj1 =null;
obj2 =null;
System.gc();
}
}
输出:
Object has been collected by the garbage collector!
Object has been collected by the garbage collector!