110
111 size_t non_taxable = free * ShenandoahPacingCycleSlack / 100;
112 size_t taxable = free - non_taxable;
113
114 double tax = 1.0 * used / taxable; // base tax for available free space
115 tax *= 1; // update-refs is phase 3 of 3, claim the remaining free
116 tax = MAX2<double>(1, tax); // never allocate more than GC processes during the phase
117 tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap
118
119 restart_with(non_taxable, tax);
120
121 log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
122 "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
123 byte_size_in_proper_unit(used), proper_unit_for_byte_size(used),
124 byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
125 byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
126 tax);
127 }
128
129 /*
130 * In idle phase, we have to pace the application to let control thread react with GC start.
131 *
132 * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
133 * it had seen recent allocations. It will naturally pace the allocations if control thread is
134 * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
135 * for applications to allocate at.
136 */
137
138 void ShenandoahPacer::setup_for_idle() {
139 assert(ShenandoahPacing, "Only be here when pacing is enabled");
140
141 size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
142 double tax = 1;
143
144 restart_with(initial, tax);
145
146 log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
147 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial),
148 tax);
149 }
|
110
111 size_t non_taxable = free * ShenandoahPacingCycleSlack / 100;
112 size_t taxable = free - non_taxable;
113
114 double tax = 1.0 * used / taxable; // base tax for available free space
115 tax *= 1; // update-refs is phase 3 of 3, claim the remaining free
116 tax = MAX2<double>(1, tax); // never allocate more than GC processes during the phase
117 tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap
118
119 restart_with(non_taxable, tax);
120
121 log_info(gc, ergo)("Pacer for Update Refs. Used: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
122 "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
123 byte_size_in_proper_unit(used), proper_unit_for_byte_size(used),
124 byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
125 byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
126 tax);
127 }
128
129 /*
130 * Traversal walks the entire heap once, and therefore we have to make assumptions about its
131 * liveness, like concurrent mark does.
132 */
133
134 void ShenandoahPacer::setup_for_traversal() {
135 assert(ShenandoahPacing, "Only be here when pacing is enabled");
136
137 size_t live = update_and_get_progress_history();
138 size_t free = _heap->free_set()->available();
139
140 size_t non_taxable = free * ShenandoahPacingCycleSlack / 100;
141 size_t taxable = free - non_taxable;
142
143 double tax = 1.0 * live / taxable; // base tax for available free space
144 tax *= ShenandoahPacingSurcharge; // additional surcharge to help unclutter heap
145
146 restart_with(non_taxable, tax);
147
148 log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "%s, Free: " SIZE_FORMAT "%s, "
149 "Non-Taxable: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
150 byte_size_in_proper_unit(live), proper_unit_for_byte_size(live),
151 byte_size_in_proper_unit(free), proper_unit_for_byte_size(free),
152 byte_size_in_proper_unit(non_taxable), proper_unit_for_byte_size(non_taxable),
153 tax);
154 }
155
156 /*
157 * In idle phase, we have to pace the application to let control thread react with GC start.
158 *
159 * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
160 * it had seen recent allocations. It will naturally pace the allocations if control thread is
161 * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
162 * for applications to allocate at.
163 */
164
165 void ShenandoahPacer::setup_for_idle() {
166 assert(ShenandoahPacing, "Only be here when pacing is enabled");
167
168 size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
169 double tax = 1;
170
171 restart_with(initial, tax);
172
173 log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "%s, Alloc Tax Rate: %.1fx",
174 byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial),
175 tax);
176 }
|