Java垃圾收集
本文讨论了Java垃圾收集(GC)这一Java编程语言中的复杂问题之一。
顾名思义,java中的垃圾收集处理自动从内存中搜索、发现和删除垃圾,而无需用户显式地执行这项工作。这里垃圾指的是未引用的对象。
有很多方法可以证明一个对象是不被引用和无用的。其中包括:
无效引用
将引用指定给另一个
匿名对象和更多
因此,垃圾回收功能会发现这些对象,并自动从内存中删除它们,从而有效地使用和管理内存。
如果你在C语言中做了同样的垃圾收集和优化,那么你将使用For()函数,而在C++中,你会使用DELTEE()方法。因此,在Java中实现了这一过程的自动化,从而减少了用户处理的麻烦。
从技术上讲,Java垃圾回收处理的是跟踪JVM(Java虚拟机)堆空间中的每个对象,并删除(删除/取消分配)未使用的对象。
垃圾回收(GC)实现有4种类型:
串行垃圾收集器
并行垃圾收集器
CMS垃圾收集器
G1垃圾收集器
串行垃圾收集器
GC的这种实现使用单个线程,并在运行时冻结所有应用程序线程。因此,它不是多线程应用程序的最佳选择。所有垃圾收集事件都在一个线程中串行执行。
它用于对暂停时间要求不高且在客户机风格的计算机上运行的应用程序。它是为单线程系统设计的,并且是JVM中较小堆大小的首选。
并行垃圾收集器
此变体是JVM的默认垃圾收集器,也称为吞吐量收集器。并行GC在管理堆时使用多个线程,这与串行GC不同。然而,和serialgc一样,它在运行时也会冻结其余的应用程序线程。
可以指定最大垃圾收集线程和暂停时间、吞吐量和占用空间(堆大小)。
CMS垃圾收集器
CMS代表并发标记清除,它使用多个GC线程同时扫描堆并标记未引用的对象,这些对象后来在扫描中被删除/取消分配。对于那些需要短时间垃圾收集暂停并且能够与GC共享资源的应用程序,它是首选。使用这种GC实现的应用程序比不使用GC实现的应用程序要慢一些,但是它们在执行垃圾收集时不会完全暂停整个应用程序。
在两种情况下,垃圾回收器的这种含义将进入停止世界(STW)模式:
初始化根的初始标记时
当算法同时运行时,应用程序更改了堆的状态;强制它返回以确保标记了正确的对象。
当一个对象从年轻一代移到老一代,而收藏家没有足够的时间在老一代中腾出空间时,就会遇到提升失败。
G1垃圾收集器
G1代表垃圾优先GC,适用于运行在具有大内存的多处理器计算机上的应用程序。与CMS收集器相比,它具有更高的性能效率。
g1gc将堆划分为一组大小相等的堆区域,并标记一个并发的全局标记阶段,以确定堆中的对象是否正在使用。
标记完成后,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!