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 39 static const double MaxRamFractionForYoung = 0.8; 40 41 size_t ParallelArguments::conservative_max_heap_alignment() { 42 return compute_heap_alignment(); 43 } 44 45 void 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 99 static size_t default_gen_alignment() { 100 return 64 * K * HeapWordSize; 101 } 102 103 void ParallelArguments::initialize_alignments() { 104 SpaceAlignment = GenAlignment = default_gen_alignment(); 105 HeapAlignment = compute_heap_alignment(); 106 } 107 108 void 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 124 void 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(). 149 void 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 198 bool ParallelArguments::is_heterogeneous_heap() { 199 return AllocateOldGenAt != NULL; 200 } 201 202 size_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 217 size_t ParallelArguments::heap_max_size_bytes() { 218 return MaxHeapSize; 219 } 220 221 CollectedHeap* ParallelArguments::create_heap() { 222 return new ParallelScavengeHeap(); 223 }