我的项目使用的是jdk11,所以垃圾回收器是G1。
内存分区与回收策略
- Region 分区机制
- G1 将堆内存划分为多个大小相等的独立区域(Region),包括 Eden、Survivor、Old 以及 Humongous 区域(用于存储大对象)。这种细粒度的分区方式使得 G1 在回收内存时可以更加灵活,不必像传统垃圾回收器那样对整个新生代或老年代进行全局回收。
- 在高并发场景下,程序会频繁创建和销毁大量对象,G1 可以根据各个 Region 中对象的存活情况和垃圾占比,优先回收垃圾最多的 Region,从而提高垃圾回收的效率,减少对应用程序的影响。
- 增量式回收
- G1 采用增量式的垃圾回收方式,将整个垃圾回收过程分成多个小的阶段进行。在每个阶段,G1 只处理一部分 Region,并且可以在应用程序运行的间隙进行回收操作,从而实现了垃圾回收与应用程序的并发执行。
- 这种方式大大减少了垃圾回收时的停顿时间,使得应用程序在高并发情况下能够保持较高的响应性能,避免了因长时间的垃圾回收停顿而导致的请求积压和响应延迟。
停顿时间可预测性
- Pause Prediction Model
- G1 引入了停顿预测模型,通过记录历史垃圾回收的时间和效果,结合当前堆内存的使用情况,预测下一次垃圾回收所需的时间。
- 在高并发场景下,应用程序对响应时间的要求非常高,G1 可以根据用户指定的最大停顿时间目标(如 -XX:MaxGCPauseMillis 参数),动态调整垃圾回收的策略和范围,确保每次垃圾回收的停顿时间都在可接受的范围内,从而保证了应用程序的稳定性和可靠性。
并发标记与整理
- 并发标记阶段
- G1 在标记阶段采用了并发标记的方式,即在应用程序运行的同时,并行地进行对象的可达性分析和标记操作。这样可以减少标记阶段对应用程序的影响,避免了传统标记 - 清除算法中标记阶段的长时间停顿。
- 在高并发场景下,大量的对象创建和销毁会导致频繁的垃圾回收,并发标记可以有效地减少这种情况下的停顿时间,提高应用程序的吞吐量。
- 局部整理
- G1 在回收垃圾的同时,会对存活对象进行局部的整理和移动,将存活对象集中到相邻的 Region 中,从而减少内存碎片的产生。
- 这种局部整理的方式不仅可以提高内存的利用率,还可以避免因内存碎片导致的大对象分配失败问题,保证了高并发应用程序在长时间运行过程中的内存稳定性。
对大内存的支持
- 高效处理大内存
- 在高并发场景下,应用程序通常需要处理大量的数据,因此需要较大的堆内存。G1 能够有效地管理和回收大内存,通过将堆内存划分为多个 Region,可以更好地利用内存资源,避免了传统垃圾回收器在处理大内存时的性能瓶颈。
*同时,G1 对大对象的处理也更加高效,通过专门的 Humongous 区域来存储大对象,避免了大对象对其他 Region 的影响,提高了垃圾回收的效率。