下面是一些Apache Spark执行器的GCViewer图:
老一代二手堆
年轻一代二手堆
GC时间
有问题的现象
我试图了解(4)中的斜率。为什么要在使用整个年轻代堆之前先启动gc(如先前的gcs阶段)?为何它会在逐渐增加之前保持单调减少约5分钟?我认为,例如,如果分配了非常大的对象(例如,从io套接字读取),则会发生这种情况。但这可能是错误的,因为那之后老一代并没有改变。我并不特别在乎这个示例,而只是在学习关于jvm内存管理的更多信息。
最佳答案
我能想到的一种可能的解释是线程本地分配块(TLAB)的结果。为了避免争用多个线程使用的指向Eden空间的单个指针,每个应用程序线程都有自己的指向Eden空间中的内存块的指针。当TLAB用尽时,将分配一个新的TLAB(这也可能涉及分配一个更大的块,以便可以消除线程分配速率之间的差异)。
这样做的含义是,当需要发生GC时,TLAB中通常会存在未使用的空间(因为一个线程需要一个新的TLAB,并且没有足够的空间容纳它)。您可能会遇到以下情况:由于其他线程的分配率,TLAB中剩余的空间量增加了。
由于这是年轻一代的整体,因此幸存者空间中的某些物体可能会按这样的速度使用,其使用率会导致占用的空间量减少。
不幸的是,从提供的数据来看,不可能给出确切的答案。