显示垃圾回收
传统的C/C++,需要程序员负责回收已经分配的内存,显示的进行垃圾回收,然而这是非常困难的事情,因为程序员往往并不知道内存应该何时被释放,内存得不到释放将会引起系统运行速度下降,也就是内存泄漏,而如果错误的回收了程序核心类库的内存,则系统会直接崩溃
隐式的垃圾回收
Java不需要程序员直接控制内存回收,内存分配和回收都是JRE在后台自动进行的,JRE会自动回收那些不再使用的内存,通常JRE会提供一个后台线程来进行检测和控制,一般在CPU空闲或者内存不足时自行进行垃圾回收,而程序员无法精确的控制垃圾回收的时间和顺序
Java的堆内存是一个运行时数据区,用来保存类的实例,Java虚拟机的堆内存中存储着正在运行的应用程序所建立的所有对象,这些对象不需要程序通过代码来显式地释放,而是由垃圾回收器来负责,所有的JVM都有一个由垃圾回收器管理的堆内存,垃圾回收是一种动态存储管理技术,它会自动shi fa 不再被程序引用的对象,按照特定的垃圾回收算法来实现内存的自动回收。
编写Java程序一个基本原则是对于不再需要的对象,不要引用他们,如果保持对他们的引用,垃圾回收机制暂时不会回收该对象,则会导致系统内存越来越少,内存越来越少则会导致GC执行的频率越来越高,最终性能严重下降
GC的发展
Java7采用G1垃圾回收器代替原有的并行标记/清除垃圾回收器(CMS)
Java8删除了HotSpot JVM中永生代内存(PermGen,用于存储一些常驻内存通常不会被回收的信息),改为使用本地内存来存储类的元数据信息,并称之为元空间(Metaspace)
Java9彻底删除了传统的CMS垃圾回收器,默认采用低暂停的G1垃圾回收器
Java11则引入了新的、实验性质的Z垃圾回收器(ZGC),其特点如下:
- 垃圾回收时暂停时间不会超过10ms
- 暂停时间不会随着堆或实时集合的大小而增加
- 可处理几百MB到几TB的堆内存
- 核心是并发垃圾回收器,从而大大降低了该垃圾回收器对程序响应速度的影响
默认情况下Java11并为启用ZGC,如果需要启动则需要运行java命令时使用如下选项:
- -XX:+UnlockExperimentalVMOptions
- -XX:+UseZGC
此外Java11还引入了实验性的Epsilon垃圾回收器,它只负责内存分配不负责回收,这个垃圾回收器主要在性能测试中比较有用,用于与其他垃圾回收器的开销/收益比进行对比