13.1、前文回顾
在上一篇文章中,我们详细分析了触发Minor GC的时机,以及对象何时会从新生代迁移到老年代。我们还讨论了为了确保新生代向老年代的内存迁移安全,需要在Minor GC之前如何检查老年代的内存空间,以及在什么情况下会触发老年代的Full GC,以及老年代的垃圾回收算法是什么。
在这篇文章中,我们将接着上篇文章的内容,通过一个真实的案例来深入理解整个对象分配以及转移到老年代的过程,以及Minor GC和Full GC的全过程。这个案例来自我们之前的一个生产系统,其中老年代频繁发生Full GC。通过这个案例,大家将更加透彻地理解整个过程。
13.2、项目背景介绍
让我们首先简要概述这个系统的案例背景。这是一个数据计算系统,它具备处理上亿条数据的强大能力。为了帮助大家更好地集中注意力理解这个系统在生产环境中与JVM相关的部分,我们会对系统本身的描述进行简化。
简而言之,这个系统的主要功能是不断地从MySQL数据库以及其他数据源中提取大量数据,然后加载到其自身的JVM内存中进行计算处理,如下图所示。
这个数据计算系统会持续地通过SQL语句和其他方式从各种数据存储中提取数据到内存中进行计算。在生产环境中,每分钟大约需要执行500次数据提取和计算的任务。由于这是一套分布式运行的系统,因此在生产环境中部署了多台机器。每台机器大致每分钟负责执行100次数据提取和计算的任务。
每次数据提取,大约会将1万条左右的数据加载到内存中进行计算,平均每次计算大约需要耗费10秒左右的时间。