Skip to content
This repository was archived by the owner on May 26, 2023. It is now read-only.

Commit 3d8dbd3

Browse files
author
Eric Abbott
committed
Tease out where time is spent inside stw
1 parent f93577b commit 3d8dbd3

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

gc_log_visualizer.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@
66
import os
77
import dateutil.parser
88

9+
class StwSubTimings:
10+
def __init__(self):
11+
self.reset()
12+
13+
def reset(self):
14+
self.ext_root_scan = 0
15+
self.update_rs = 0
16+
self.scan_rs = 0
17+
self.object_copy = 0
18+
self.termination = 0
19+
self.other = 0
20+
21+
def unknown_time(self, total):
22+
if total:
23+
return int((total * 1000) - self.ext_root_scan - self.update_rs - self.scan_rs - self.object_copy - self.termination - self.other)
24+
else:
25+
return 0
26+
927
class LogParser:
1028
heapG1GCPattern = '\s*\[Eden: ([0-9.]+)([BKMG])\(([0-9.]+)([BKMG])\)->[0-9.BKMG()]+ Survivors: ([0-9.]+)([BKMG])->([0-9.]+)([BKMG]) Heap: ([0-9.]+)([BKMG])\([0-9.BKMG]+\)->([0-9.]+)([BKMG])\([0-9.BKMG]+\)'
1129
parallelPattern = '\s*\[PSYoungGen: ([0-9.]+)([BKMG])->([0-9.]+)([BKMG])\([0-9.MKBG]+\)\] ([0-9.]+)([MKBG])->([0-9.]+)([MKBG])\([0-9.MKBG]+\),'
@@ -57,6 +75,7 @@ def __init__(self, input_file):
5775
self.last_minute = -1
5876
self.reset_pause_counts()
5977
self.occupancy_threshold = None
78+
self.stw = StwSubTimings()
6079

6180
def cleanup(self):
6281
os.unlink(self.pause_file.name)
@@ -103,11 +122,29 @@ def gnuplot(self, name, start, end):
103122
os.system(gnuplot_cmd)
104123
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:2'" % (self.size, name, xrange, self.pause_file.name)
105124
os.system(gnuplot_cmd)
125+
126+
# Separate young and mixed stw events
106127
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-young-stw.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:2'" % (self.size, name, xrange, self.young_pause_file.name)
107128
os.system(gnuplot_cmd)
108129
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-mixed-stw.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:2'" % (self.size, name, xrange, self.mixed_pause_file.name)
109130
os.system(gnuplot_cmd)
110131

132+
# Stw sub-timings
133+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-ext-root-scan.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:3'" % (self.size, name, xrange, self.pause_file.name)
134+
os.system(gnuplot_cmd)
135+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-update-rs.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:4'" % (self.size, name, xrange, self.pause_file.name)
136+
os.system(gnuplot_cmd)
137+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-scan-rs.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:5'" % (self.size, name, xrange, self.pause_file.name)
138+
os.system(gnuplot_cmd)
139+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-object-copy.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:6'" % (self.size, name, xrange, self.pause_file.name)
140+
os.system(gnuplot_cmd)
141+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-termination.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:7'" % (self.size, name, xrange, self.pause_file.name)
142+
os.system(gnuplot_cmd)
143+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-other.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:8'" % (self.size, name, xrange, self.pause_file.name)
144+
os.system(gnuplot_cmd)
145+
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-stw-unknown.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:9'" % (self.size, name, xrange, self.pause_file.name)
146+
os.system(gnuplot_cmd)
147+
111148
# total pause time
112149
gnuplot_cmd = "gnuplot -e 'set term png size %s; set output \"%s-total-pause.png\"; set xdata time; set timefmt \"%%Y-%%m-%%d:%%H:%%M:%%S\"; %s plot \"%s\" using 1:8 title \"%% of time in gc\"'" % (self.size, name, xrange, self.pause_count_file.name)
113150
os.system(gnuplot_cmd)
@@ -210,17 +247,21 @@ def parse_log(self):
210247
if not self.occupancy_threshold:
211248
self.collect_occupancy_threshold_pattern(line)
212249

250+
# collect where time is spent inside stw
251+
self.collect_stw_sub_timings(line)
252+
213253
# This needs to be last
214254
if self.line_has_pause_time(line):
215255
self.output_data()
256+
self.stw.reset()
216257

217258
def output_data(self):
218259
if self.mixed_duration_count == 0:
219260
self.young_pause_file.write("%s %.6f\n" % (self.timestamp_string(), self.pause_time))
220261
else:
221262
self.mixed_pause_file.write("%s %.6f\n" % (self.timestamp_string(), self.pause_time))
222-
223-
self.pause_file.write("%s %.6f\n" % (self.timestamp_string(), self.pause_time))
263+
264+
self.pause_file.write("%s %.6f %d %d %d %d %d %d %d\n" % (self.timestamp_string(), self.pause_time, self.stw.ext_root_scan, self.stw.update_rs, self.stw.scan_rs, self.stw.object_copy, self.stw.termination, self.stw.other, self.stw.unknown_time(self.pause_time)))
224265
self.young_file.write("%s %s %s %s %s %s\n" % (self.timestamp_string(), self.pre_gc_young, self.pre_gc_young_target, self.pre_gc_total - self.pre_gc_young, self.pre_gc_total, self.tenured_delta))
225266

226267
# clean this up, full_gc's should probably graph
@@ -337,6 +378,24 @@ def collect_reclaimable(self, line):
337378
if m and int(float(m.group(2))) >= int(m.group(3)) and self.timestamp:
338379
self.reclaimable_file.write("%s %d\n" % (self.timestamp_string(), long(m.group(1)) / 1048576))
339380

381+
def collect_stw_sub_timings(self, line):
382+
if re.match('^[ ]+\[.*', line):
383+
self.stw.ext_root_scan = self.parseMaxTiming('Ext Root Scanning', line, self.stw.ext_root_scan)
384+
self.stw.update_rs = self.parseMaxTiming('Update RS', line, self.stw.update_rs)
385+
self.stw.scan_rs = self.parseMaxTiming('Scan RS', line, self.stw.scan_rs)
386+
self.stw.object_copy = self.parseMaxTiming('Object Copy', line, self.stw.object_copy)
387+
self.stw.termination = self.parseMaxTiming('Termination', line, self.stw.termination)
388+
m = re.match('^[ ]+\[Other: ([0-9.]+).*', line)
389+
if m:
390+
self.stw.other = int(float(m.group(1)))
391+
392+
def parseMaxTiming(self, term, line, current_value):
393+
m = re.match("^[ ]+\[%s .* Max: ([0-9]+)\.[0-9],.*" % (term), line)
394+
if m:
395+
return int(float(m.group(1)))
396+
else:
397+
return current_value
398+
340399
def line_has_gc(self, line):
341400
m = re.match(LogParser.heapG1GCPattern, line, flags=0)
342401
if m:

0 commit comments

Comments
 (0)