@@ -145,13 +145,16 @@ private[spark] class Executor(
145145 }
146146 }
147147
148+ private def gcTime = ManagementFactory .getGarbageCollectorMXBeans.map(_.getCollectionTime).sum
149+
148150 class TaskRunner (
149151 execBackend : ExecutorBackend , val taskId : Long , taskName : String , serializedTask : ByteBuffer )
150152 extends Runnable {
151153
152154 @ volatile private var killed = false
153155 @ volatile var task : Task [Any ] = _
154156 @ volatile var attemptedTask : Option [Task [Any ]] = None
157+ @ volatile var startGCTime : Long = _
155158
156159 def kill (interruptThread : Boolean ) {
157160 logInfo(s " Executor is trying to kill $taskName (TID $taskId) " )
@@ -168,8 +171,7 @@ private[spark] class Executor(
168171 logInfo(s " Running $taskName (TID $taskId) " )
169172 execBackend.statusUpdate(taskId, TaskState .RUNNING , EMPTY_BYTE_BUFFER )
170173 var taskStart : Long = 0
171- def gcTime = ManagementFactory .getGarbageCollectorMXBeans.map(_.getCollectionTime).sum
172- val startGCTime = gcTime
174+ startGCTime = gcTime
173175
174176 try {
175177 val (taskFiles, taskJars, taskBytes) = Task .deserializeWithDependencies(serializedTask)
@@ -376,10 +378,13 @@ private[spark] class Executor(
376378
377379 while (! isStopped) {
378380 val tasksMetrics = new ArrayBuffer [(Long , TaskMetrics )]()
381+ val curGCTime = gcTime
382+
379383 for (taskRunner <- runningTasks.values()) {
380384 if (! taskRunner.attemptedTask.isEmpty) {
381385 Option (taskRunner.task).flatMap(_.metrics).foreach { metrics =>
382386 metrics.updateShuffleReadMetrics
387+ metrics.jvmGCTime = curGCTime - taskRunner.startGCTime
383388 if (isLocal) {
384389 // JobProgressListener will hold an reference of it during
385390 // onExecutorMetricsUpdate(), then JobProgressListener can not see
0 commit comments