Wed, 07 Jan 2015 15:15:37 +0100
8048179: Early reclaim of large objects that are referenced by a few objects
Summary: Push the remembered sets of large objects with few referenced into the dirty card queue at the beginning of the evacuation so that they may end up with zero remembered set entries at the end of the collection, and are potentially reclaimed. Also improve timing measurements of the early reclaim mechanism, and shorten flag names.
Reviewed-by: brutisso, jmasa, dfazunen
1 /*
2 * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
28 #include "memory/allocation.hpp"
30 class LineBuffer;
32 template <class T> class WorkerDataArray;
34 class G1GCPhaseTimes : public CHeapObj<mtGC> {
35 friend class G1GCParPhasePrinter;
37 uint _active_gc_threads;
38 uint _max_gc_threads;
40 public:
41 enum GCParPhases {
42 GCWorkerStart,
43 ExtRootScan,
44 ThreadRoots,
45 StringTableRoots,
46 UniverseRoots,
47 JNIRoots,
48 ObjectSynchronizerRoots,
49 FlatProfilerRoots,
50 ManagementRoots,
51 SystemDictionaryRoots,
52 CLDGRoots,
53 JVMTIRoots,
54 CodeCacheRoots,
55 CMRefRoots,
56 WaitForStrongCLD,
57 WeakCLDRoots,
58 SATBFiltering,
59 UpdateRS,
60 ScanRS,
61 CodeRoots,
62 ObjCopy,
63 Termination,
64 Other,
65 GCWorkerTotal,
66 GCWorkerEnd,
67 StringDedupQueueFixup,
68 StringDedupTableFixup,
69 RedirtyCards,
70 GCParPhasesSentinel
71 };
73 private:
74 // Markers for grouping the phases in the GCPhases enum above
75 static const int GCMainParPhasesLast = GCWorkerEnd;
76 static const int StringDedupPhasesFirst = StringDedupQueueFixup;
77 static const int StringDedupPhasesLast = StringDedupTableFixup;
79 WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
80 WorkerDataArray<size_t>* _update_rs_processed_buffers;
81 WorkerDataArray<size_t>* _termination_attempts;
82 WorkerDataArray<size_t>* _redirtied_cards;
84 double _cur_collection_par_time_ms;
85 double _cur_collection_code_root_fixup_time_ms;
86 double _cur_strong_code_root_purge_time_ms;
88 double _cur_evac_fail_recalc_used;
89 double _cur_evac_fail_restore_remsets;
90 double _cur_evac_fail_remove_self_forwards;
92 double _cur_string_dedup_fixup_time_ms;
94 double _cur_clear_ct_time_ms;
95 double _cur_ref_proc_time_ms;
96 double _cur_ref_enq_time_ms;
98 double _cur_collection_start_sec;
99 double _root_region_scan_wait_time_ms;
101 double _recorded_young_cset_choice_time_ms;
102 double _recorded_non_young_cset_choice_time_ms;
104 double _recorded_redirty_logged_cards_time_ms;
106 double _recorded_young_free_cset_time_ms;
107 double _recorded_non_young_free_cset_time_ms;
109 double _cur_fast_reclaim_humongous_time_ms;
110 double _cur_fast_reclaim_humongous_register_time_ms;
111 size_t _cur_fast_reclaim_humongous_total;
112 size_t _cur_fast_reclaim_humongous_candidates;
113 size_t _cur_fast_reclaim_humongous_reclaimed;
115 double _cur_verify_before_time_ms;
116 double _cur_verify_after_time_ms;
118 // Helper methods for detailed logging
119 void print_stats(int level, const char* str, double value);
120 void print_stats(int level, const char* str, size_t value);
121 void print_stats(int level, const char* str, double value, uint workers);
123 public:
124 G1GCPhaseTimes(uint max_gc_threads);
125 void note_gc_start(uint active_gc_threads, bool mark_in_progress);
126 void note_gc_end();
127 void print(double pause_time_sec);
129 // record the time a phase took in seconds
130 void record_time_secs(GCParPhases phase, uint worker_i, double secs);
132 // add a number of seconds to a phase
133 void add_time_secs(GCParPhases phase, uint worker_i, double secs);
135 void record_thread_work_item(GCParPhases phase, uint worker_i, size_t count);
137 // return the average time for a phase in milliseconds
138 double average_time_ms(GCParPhases phase);
140 size_t sum_thread_work_items(GCParPhases phase);
142 private:
143 double get_time_ms(GCParPhases phase, uint worker_i);
144 double sum_time_ms(GCParPhases phase);
145 double min_time_ms(GCParPhases phase);
146 double max_time_ms(GCParPhases phase);
147 size_t get_thread_work_item(GCParPhases phase, uint worker_i);
148 double average_thread_work_items(GCParPhases phase);
149 size_t min_thread_work_items(GCParPhases phase);
150 size_t max_thread_work_items(GCParPhases phase);
152 public:
154 void record_clear_ct_time(double ms) {
155 _cur_clear_ct_time_ms = ms;
156 }
158 void record_par_time(double ms) {
159 _cur_collection_par_time_ms = ms;
160 }
162 void record_code_root_fixup_time(double ms) {
163 _cur_collection_code_root_fixup_time_ms = ms;
164 }
166 void record_strong_code_root_purge_time(double ms) {
167 _cur_strong_code_root_purge_time_ms = ms;
168 }
170 void record_evac_fail_recalc_used_time(double ms) {
171 _cur_evac_fail_recalc_used = ms;
172 }
174 void record_evac_fail_restore_remsets(double ms) {
175 _cur_evac_fail_restore_remsets = ms;
176 }
178 void record_evac_fail_remove_self_forwards(double ms) {
179 _cur_evac_fail_remove_self_forwards = ms;
180 }
182 void record_string_dedup_fixup_time(double ms) {
183 _cur_string_dedup_fixup_time_ms = ms;
184 }
186 void record_ref_proc_time(double ms) {
187 _cur_ref_proc_time_ms = ms;
188 }
190 void record_ref_enq_time(double ms) {
191 _cur_ref_enq_time_ms = ms;
192 }
194 void record_root_region_scan_wait_time(double time_ms) {
195 _root_region_scan_wait_time_ms = time_ms;
196 }
198 void record_young_free_cset_time_ms(double time_ms) {
199 _recorded_young_free_cset_time_ms = time_ms;
200 }
202 void record_non_young_free_cset_time_ms(double time_ms) {
203 _recorded_non_young_free_cset_time_ms = time_ms;
204 }
206 void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) {
207 _cur_fast_reclaim_humongous_register_time_ms = time_ms;
208 _cur_fast_reclaim_humongous_total = total;
209 _cur_fast_reclaim_humongous_candidates = candidates;
210 }
212 void record_fast_reclaim_humongous_time_ms(double value, size_t reclaimed) {
213 _cur_fast_reclaim_humongous_time_ms = value;
214 _cur_fast_reclaim_humongous_reclaimed = reclaimed;
215 }
217 void record_young_cset_choice_time_ms(double time_ms) {
218 _recorded_young_cset_choice_time_ms = time_ms;
219 }
221 void record_non_young_cset_choice_time_ms(double time_ms) {
222 _recorded_non_young_cset_choice_time_ms = time_ms;
223 }
225 void record_redirty_logged_cards_time_ms(double time_ms) {
226 _recorded_redirty_logged_cards_time_ms = time_ms;
227 }
229 void record_cur_collection_start_sec(double time_ms) {
230 _cur_collection_start_sec = time_ms;
231 }
233 void record_verify_before_time_ms(double time_ms) {
234 _cur_verify_before_time_ms = time_ms;
235 }
237 void record_verify_after_time_ms(double time_ms) {
238 _cur_verify_after_time_ms = time_ms;
239 }
241 double accounted_time_ms();
243 double cur_collection_start_sec() {
244 return _cur_collection_start_sec;
245 }
247 double cur_collection_par_time_ms() {
248 return _cur_collection_par_time_ms;
249 }
251 double cur_clear_ct_time_ms() {
252 return _cur_clear_ct_time_ms;
253 }
255 double root_region_scan_wait_time_ms() {
256 return _root_region_scan_wait_time_ms;
257 }
259 double young_cset_choice_time_ms() {
260 return _recorded_young_cset_choice_time_ms;
261 }
263 double young_free_cset_time_ms() {
264 return _recorded_young_free_cset_time_ms;
265 }
267 double non_young_cset_choice_time_ms() {
268 return _recorded_non_young_cset_choice_time_ms;
269 }
271 double non_young_free_cset_time_ms() {
272 return _recorded_non_young_free_cset_time_ms;
273 }
275 double fast_reclaim_humongous_time_ms() {
276 return _cur_fast_reclaim_humongous_time_ms;
277 }
278 };
280 class G1GCParPhaseTimesTracker : public StackObj {
281 double _start_time;
282 G1GCPhaseTimes::GCParPhases _phase;
283 G1GCPhaseTimes* _phase_times;
284 uint _worker_id;
285 public:
286 G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
287 ~G1GCParPhaseTimesTracker();
288 };
290 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP