1/*
2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#include "precompiled.hpp"
27#include "gc/parallel/parallelArguments.hpp"
28#include "gc/parallel/parallelScavengeHeap.hpp"
29#include "gc/shared/adaptiveSizePolicy.hpp"
30#include "gc/shared/gcArguments.hpp"
31#include "gc/shared/genArguments.hpp"
32#include "gc/shared/workerPolicy.hpp"
33#include "logging/log.hpp"
34#include "runtime/globals.hpp"
35#include "runtime/globals_extension.hpp"
36#include "runtime/java.hpp"
37#include "utilities/defaultStream.hpp"
38
39static const double MaxRamFractionForYoung = 0.8;
40
41size_t ParallelArguments::conservative_max_heap_alignment() {
42 return compute_heap_alignment();
43}
44
45void ParallelArguments::initialize() {
46 GCArguments::initialize();
47 assert(UseParallelGC || UseParallelOldGC, "Error");
48 // Enable ParallelOld unless it was explicitly disabled (cmd line or rc file).
49 if (FLAG_IS_DEFAULT(UseParallelOldGC)) {
50 FLAG_SET_DEFAULT(UseParallelOldGC, true);
51 }
52 FLAG_SET_DEFAULT(UseParallelGC, true);
53
54 // If no heap maximum was requested explicitly, use some reasonable fraction
55 // of the physical memory, up to a maximum of 1GB.
56 FLAG_SET_DEFAULT(ParallelGCThreads,
57 WorkerPolicy::parallel_worker_threads());
58 if (ParallelGCThreads == 0) {
59 jio_fprintf(defaultStream::error_stream(),
60 "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n");
61 vm_exit(1);
62 }
63
64 if (UseAdaptiveSizePolicy) {
65 // We don't want to limit adaptive heap sizing's freedom to adjust the heap
66 // unless the user actually sets these flags.
67 if (FLAG_IS_DEFAULT(MinHeapFreeRatio)) {
68 FLAG_SET_DEFAULT(MinHeapFreeRatio, 0);
69 }
70 if (FLAG_IS_DEFAULT(MaxHeapFreeRatio)) {
71 FLAG_SET_DEFAULT(MaxHeapFreeRatio, 100);
72 }
73 }
74
75 // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the
76 // SurvivorRatio has been set, reset their default values to SurvivorRatio +
77 // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger.
78 // See CR 6362902 for details.
79 if (!FLAG_IS_DEFAULT(SurvivorRatio)) {
80 if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) {
81 FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2);
82 }
83 if (FLAG_IS_DEFAULT(MinSurvivorRatio)) {
84 FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2);
85 }
86 }
87
88 if (UseParallelOldGC) {
89 // Par compact uses lower default values since they are treated as
90 // minimums. These are different defaults because of the different
91 // interpretation and are not ergonomically set.
92 if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) {
93 FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1);
94 }
95 }
96}
97
98// The alignment used for boundary between young gen and old gen
99static size_t default_gen_alignment() {
100 return 64 * K * HeapWordSize;
101}
102
103void ParallelArguments::initialize_alignments() {
104 SpaceAlignment = GenAlignment = default_gen_alignment();
105 HeapAlignment = compute_heap_alignment();
106}
107
108void ParallelArguments::initialize_heap_flags_and_sizes_one_pass() {
109 // Do basic sizing work
110 GenArguments::initialize_heap_flags_and_sizes();
111
112 // The survivor ratio's are calculated "raw", unlike the
113 // default gc, which adds 2 to the ratio value. We need to
114 // make sure the values are valid before using them.
115 if (MinSurvivorRatio < 3) {
116 FLAG_SET_ERGO(MinSurvivorRatio, 3);
117 }
118
119 if (InitialSurvivorRatio < 3) {
120 FLAG_SET_ERGO(InitialSurvivorRatio, 3);
121 }
122}
123
124void ParallelArguments::initialize_heap_flags_and_sizes() {
125 if (is_heterogeneous_heap()) {
126 initialize_heterogeneous();
127 }
128
129 initialize_heap_flags_and_sizes_one_pass();
130
131 const size_t max_page_sz = os::page_size_for_region_aligned(MaxHeapSize, 8);
132 const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
133 const size_t min_page_sz = os::page_size_for_region_aligned(MinHeapSize, min_pages);
134 const size_t page_sz = MIN2(max_page_sz, min_page_sz);
135
136 // Can a page size be something else than a power of two?
137 assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2");
138 size_t new_alignment = align_up(page_sz, GenAlignment);
139 if (new_alignment != GenAlignment) {
140 GenAlignment = new_alignment;
141 SpaceAlignment = new_alignment;
142 // Redo everything from the start
143 initialize_heap_flags_and_sizes_one_pass();
144 }
145}
146
147// Check the available dram memory to limit NewSize and MaxNewSize before
148// calling base class initialize_flags().
149void ParallelArguments::initialize_heterogeneous() {
150 FormatBuffer<100> calc_str("");
151
152 julong phys_mem;
153 // If MaxRam is specified, we use that as maximum physical memory available.
154 if (FLAG_IS_DEFAULT(MaxRAM)) {
155 phys_mem = os::physical_memory();
156 calc_str.append("Physical_Memory");
157 } else {
158 phys_mem = (julong)MaxRAM;
159 calc_str.append("MaxRAM");
160 }
161
162 julong reasonable_max = phys_mem;
163
164 // If either MaxRAMFraction or MaxRAMPercentage is specified, we use them to calculate
165 // reasonable max size of young generation.
166 if (!FLAG_IS_DEFAULT(MaxRAMFraction)) {
167 reasonable_max = (julong)(phys_mem / MaxRAMFraction);
168 calc_str.append(" / MaxRAMFraction");
169 } else if (!FLAG_IS_DEFAULT(MaxRAMPercentage)) {
170 reasonable_max = (julong)((phys_mem * MaxRAMPercentage) / 100);
171 calc_str.append(" * MaxRAMPercentage / 100");
172 } else {
173 // We use our own fraction to calculate max size of young generation.
174 reasonable_max = phys_mem * MaxRamFractionForYoung;
175 calc_str.append(" * %0.2f", MaxRamFractionForYoung);
176 }
177 reasonable_max = align_up(reasonable_max, GenAlignment);
178
179 if (MaxNewSize > reasonable_max) {
180 if (FLAG_IS_CMDLINE(MaxNewSize)) {
181 log_warning(gc, ergo)("Setting MaxNewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s))",
182 (size_t)reasonable_max, calc_str.buffer());
183 } else {
184 log_info(gc, ergo)("Setting MaxNewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s)). "
185 "Dram usage can be lowered by setting MaxNewSize to a lower value", (size_t)reasonable_max, calc_str.buffer());
186 }
187 MaxNewSize = reasonable_max;
188 }
189 if (NewSize > reasonable_max) {
190 if (FLAG_IS_CMDLINE(NewSize)) {
191 log_warning(gc, ergo)("Setting NewSize to " SIZE_FORMAT " based on dram available (calculation = align(%s))",
192 (size_t)reasonable_max, calc_str.buffer());
193 }
194 NewSize = reasonable_max;
195 }
196}
197
198bool ParallelArguments::is_heterogeneous_heap() {
199 return AllocateOldGenAt != NULL;
200}
201
202size_t ParallelArguments::heap_reserved_size_bytes() {
203 if (!is_heterogeneous_heap() || !UseAdaptiveGCBoundary) {
204 return MaxHeapSize;
205 }
206
207 // Heterogeneous heap and adaptive size gc boundary
208
209 // This is the size that young gen can grow to, when UseAdaptiveGCBoundary is true.
210 size_t max_yg_size = MaxHeapSize - MinOldSize;
211 // This is the size that old gen can grow to, when UseAdaptiveGCBoundary is true.
212 size_t max_old_size = MaxHeapSize - MinNewSize;
213
214 return max_yg_size + max_old_size;
215}
216
217size_t ParallelArguments::heap_max_size_bytes() {
218 return MaxHeapSize;
219}
220
221CollectedHeap* ParallelArguments::create_heap() {
222 return new ParallelScavengeHeap();
223}
224