blob: a29a27310cf05909e3dd2cc9f164b0b6cc62c4c3 [file] [log] [blame]
J. Duke81537792007-12-01 00:00:00 +00001/*
Coleen Phillimore4b956222017-03-15 10:25:37 -04002 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
J. Duke81537792007-12-01 00:00:00 +00003 * 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 *
Erik Trimbleba7c1732010-05-27 19:08:38 -070019 * 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.
J. Duke81537792007-12-01 00:00:00 +000022 *
23 */
24
Stefan Karlsson8006fe82010-11-23 13:22:55 -080025#include "precompiled.hpp"
26#include "classfile/systemDictionary.hpp"
27#include "classfile/vmSymbols.hpp"
Per Lidén4dc240f2015-05-13 15:16:06 +020028#include "gc/serial/defNewGeneration.hpp"
29#include "gc/shared/space.hpp"
Erik Helin604a75f2013-06-26 16:58:37 +020030#include "memory/metaspace.hpp"
Stefan Karlsson8006fe82010-11-23 13:22:55 -080031#include "oops/oop.inline.hpp"
32#include "runtime/handles.inline.hpp"
33#include "runtime/javaCalls.hpp"
Goetz Lindenmaier6e6f0722014-04-29 15:17:27 +020034#include "runtime/orderAccess.inline.hpp"
Stefan Karlsson8006fe82010-11-23 13:22:55 -080035#include "services/lowMemoryDetector.hpp"
36#include "services/management.hpp"
37#include "services/memoryManager.hpp"
38#include "services/memoryPool.hpp"
Erik Helin604a75f2013-06-26 16:58:37 +020039#include "utilities/globalDefinitions.hpp"
Stefan Karlsson207fadd2015-03-18 10:51:00 +010040#include "utilities/macros.hpp"
41#if INCLUDE_ALL_GCS
Per Lidén4dc240f2015-05-13 15:16:06 +020042#include "gc/cms/compactibleFreeListSpace.hpp"
Stefan Karlsson207fadd2015-03-18 10:51:00 +010043#endif
J. Duke81537792007-12-01 00:00:00 +000044
45MemoryPool::MemoryPool(const char* name,
46 PoolType type,
47 size_t init_size,
48 size_t max_size,
49 bool support_usage_threshold,
50 bool support_gc_threshold) {
51 _name = name;
52 _initial_size = init_size;
53 _max_size = max_size;
Lois Foltan5ff71862014-05-29 08:58:51 -040054 (void)const_cast<instanceOop&>(_memory_pool_obj = instanceOop(NULL));
J. Duke81537792007-12-01 00:00:00 +000055 _available_for_allocation = true;
56 _num_managers = 0;
57 _type = type;
58
59 // initialize the max and init size of collection usage
60 _after_gc_usage = MemoryUsage(_initial_size, 0, 0, _max_size);
61
62 _usage_sensor = NULL;
63 _gc_usage_sensor = NULL;
64 // usage threshold supports both high and low threshold
65 _usage_threshold = new ThresholdSupport(support_usage_threshold, support_usage_threshold);
66 // gc usage threshold supports only high threshold
67 _gc_usage_threshold = new ThresholdSupport(support_gc_threshold, support_gc_threshold);
68}
69
70void MemoryPool::add_manager(MemoryManager* mgr) {
71 assert(_num_managers < MemoryPool::max_num_managers, "_num_managers exceeds the max");
72 if (_num_managers < MemoryPool::max_num_managers) {
73 _managers[_num_managers] = mgr;
74 _num_managers++;
75 }
76}
77
78
79// Returns an instanceHandle of a MemoryPool object.
80// It creates a MemoryPool instance when the first time
81// this function is called.
82instanceOop MemoryPool::get_memory_pool_instance(TRAPS) {
83 // Must do an acquire so as to force ordering of subsequent
84 // loads from anything _memory_pool_obj points to or implies.
85 instanceOop pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
86 if (pool_obj == NULL) {
87 // It's ok for more than one thread to execute the code up to the locked region.
88 // Extra pool instances will just be gc'ed.
Coleen Phillimore4b956222017-03-15 10:25:37 -040089 InstanceKlass* ik = Management::sun_management_ManagementFactoryHelper_klass(CHECK_NULL);
J. Duke81537792007-12-01 00:00:00 +000090
91 Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL);
92 jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
93 jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L);
94
95 JavaValue result(T_OBJECT);
96 JavaCallArguments args;
97 args.push_oop(pool_name); // Argument 1
98 args.push_int((int) is_heap()); // Argument 2
99
Coleen Phillimore7b4f8072011-01-27 16:11:27 -0800100 Symbol* method_name = vmSymbols::createMemoryPool_name();
101 Symbol* signature = vmSymbols::createMemoryPool_signature();
J. Duke81537792007-12-01 00:00:00 +0000102
103 args.push_long(usage_threshold_value); // Argument 3
104 args.push_long(gc_usage_threshold_value); // Argument 4
105
106 JavaCalls::call_static(&result,
107 ik,
108 method_name,
109 signature,
110 &args,
111 CHECK_NULL);
112
113 instanceOop p = (instanceOop) result.get_jobject();
114 instanceHandle pool(THREAD, p);
115
116 {
117 // Get lock since another thread may have create the instance
118 MutexLocker ml(Management_lock);
119
120 // Check if another thread has created the pool. We reload
121 // _memory_pool_obj here because some other thread may have
122 // initialized it while we were executing the code before the lock.
123 //
124 // The lock has done an acquire, so the load can't float above it,
125 // but we need to do a load_acquire as above.
126 pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj);
127 if (pool_obj != NULL) {
128 return pool_obj;
129 }
130
131 // Get the address of the object we created via call_special.
132 pool_obj = pool();
133
134 // Use store barrier to make sure the memory accesses associated
135 // with creating the pool are visible before publishing its address.
136 // The unlock will publish the store to _memory_pool_obj because
137 // it does a release first.
138 OrderAccess::release_store_ptr(&_memory_pool_obj, pool_obj);
139 }
140 }
141
142 return pool_obj;
143}
144
145inline static size_t get_max_value(size_t val1, size_t val2) {
146 return (val1 > val2 ? val1 : val2);
147}
148
149void MemoryPool::record_peak_memory_usage() {
150 // Caller in JDK is responsible for synchronization -
151 // acquire the lock for this memory pool before calling VM
152 MemoryUsage usage = get_memory_usage();
153 size_t peak_used = get_max_value(usage.used(), _peak_usage.used());
154 size_t peak_committed = get_max_value(usage.committed(), _peak_usage.committed());
155 size_t peak_max_size = get_max_value(usage.max_size(), _peak_usage.max_size());
156
157 _peak_usage = MemoryUsage(initial_size(), peak_used, peak_committed, peak_max_size);
158}
159
160static void set_sensor_obj_at(SensorInfo** sensor_ptr, instanceHandle sh) {
161 assert(*sensor_ptr == NULL, "Should be called only once");
162 SensorInfo* sensor = new SensorInfo();
163 sensor->set_sensor(sh());
164 *sensor_ptr = sensor;
165}
166
167void MemoryPool::set_usage_sensor_obj(instanceHandle sh) {
168 set_sensor_obj_at(&_usage_sensor, sh);
169}
170
171void MemoryPool::set_gc_usage_sensor_obj(instanceHandle sh) {
172 set_sensor_obj_at(&_gc_usage_sensor, sh);
173}
174
175void MemoryPool::oops_do(OopClosure* f) {
176 f->do_oop((oop*) &_memory_pool_obj);
177 if (_usage_sensor != NULL) {
178 _usage_sensor->oops_do(f);
179 }
180 if (_gc_usage_sensor != NULL) {
181 _gc_usage_sensor->oops_do(f);
182 }
183}
184
185ContiguousSpacePool::ContiguousSpacePool(ContiguousSpace* space,
186 const char* name,
187 PoolType type,
188 size_t max_size,
189 bool support_usage_threshold) :
190 CollectedMemoryPool(name, type, space->capacity(), max_size,
191 support_usage_threshold), _space(space) {
192}
193
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100194size_t ContiguousSpacePool::used_in_bytes() {
195 return space()->used();
196}
197
J. Duke81537792007-12-01 00:00:00 +0000198MemoryUsage ContiguousSpacePool::get_memory_usage() {
199 size_t maxSize = (available_for_allocation() ? max_size() : 0);
200 size_t used = used_in_bytes();
201 size_t committed = _space->capacity();
202
203 return MemoryUsage(initial_size(), used, committed, maxSize);
204}
205
Jesper Wilhelmsson49fb9142015-08-18 21:32:21 +0200206SurvivorContiguousSpacePool::SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
J. Duke81537792007-12-01 00:00:00 +0000207 const char* name,
208 PoolType type,
209 size_t max_size,
210 bool support_usage_threshold) :
Jesper Wilhelmsson49fb9142015-08-18 21:32:21 +0200211 CollectedMemoryPool(name, type, young_gen->from()->capacity(), max_size,
212 support_usage_threshold), _young_gen(young_gen) {
J. Duke81537792007-12-01 00:00:00 +0000213}
214
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100215size_t SurvivorContiguousSpacePool::used_in_bytes() {
Jesper Wilhelmsson49fb9142015-08-18 21:32:21 +0200216 return _young_gen->from()->used();
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100217}
218
219size_t SurvivorContiguousSpacePool::committed_in_bytes() {
Jesper Wilhelmsson49fb9142015-08-18 21:32:21 +0200220 return _young_gen->from()->capacity();
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100221}
222
J. Duke81537792007-12-01 00:00:00 +0000223MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
224 size_t maxSize = (available_for_allocation() ? max_size() : 0);
225 size_t used = used_in_bytes();
226 size_t committed = committed_in_bytes();
227
228 return MemoryUsage(initial_size(), used, committed, maxSize);
229}
230
Joseph Provino698fba92013-01-23 13:02:39 -0500231#if INCLUDE_ALL_GCS
J. Duke81537792007-12-01 00:00:00 +0000232CompactibleFreeListSpacePool::CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
233 const char* name,
234 PoolType type,
235 size_t max_size,
236 bool support_usage_threshold) :
237 CollectedMemoryPool(name, type, space->capacity(), max_size,
238 support_usage_threshold), _space(space) {
239}
240
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100241size_t CompactibleFreeListSpacePool::used_in_bytes() {
242 return _space->used();
243}
244
J. Duke81537792007-12-01 00:00:00 +0000245MemoryUsage CompactibleFreeListSpacePool::get_memory_usage() {
246 size_t maxSize = (available_for_allocation() ? max_size() : 0);
247 size_t used = used_in_bytes();
248 size_t committed = _space->capacity();
249
250 return MemoryUsage(initial_size(), used, committed, maxSize);
251}
Joseph Provino698fba92013-01-23 13:02:39 -0500252#endif // INCLUDE_ALL_GCS
J. Duke81537792007-12-01 00:00:00 +0000253
254GenerationPool::GenerationPool(Generation* gen,
255 const char* name,
256 PoolType type,
257 bool support_usage_threshold) :
258 CollectedMemoryPool(name, type, gen->capacity(), gen->max_capacity(),
259 support_usage_threshold), _gen(gen) {
260}
261
Stefan Karlsson207fadd2015-03-18 10:51:00 +0100262size_t GenerationPool::used_in_bytes() {
263 return _gen->used();
264}
265
J. Duke81537792007-12-01 00:00:00 +0000266MemoryUsage GenerationPool::get_memory_usage() {
267 size_t used = used_in_bytes();
268 size_t committed = _gen->capacity();
269 size_t maxSize = (available_for_allocation() ? max_size() : 0);
270
271 return MemoryUsage(initial_size(), used, committed, maxSize);
272}
273
274CodeHeapPool::CodeHeapPool(CodeHeap* codeHeap, const char* name, bool support_usage_threshold) :
275 MemoryPool(name, NonHeap, codeHeap->capacity(), codeHeap->max_capacity(),
276 support_usage_threshold, false), _codeHeap(codeHeap) {
277}
278
279MemoryUsage CodeHeapPool::get_memory_usage() {
280 size_t used = used_in_bytes();
281 size_t committed = _codeHeap->capacity();
282 size_t maxSize = (available_for_allocation() ? max_size() : 0);
283
284 return MemoryUsage(initial_size(), used, committed, maxSize);
285}
Erik Helin604a75f2013-06-26 16:58:37 +0200286
287MetaspacePool::MetaspacePool() :
Erik Helin2cab7ea2013-09-17 20:59:07 +0200288 MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { }
Erik Helin604a75f2013-06-26 16:58:37 +0200289
290MemoryUsage MetaspacePool::get_memory_usage() {
Erik Helin2cab7ea2013-09-17 20:59:07 +0200291 size_t committed = MetaspaceAux::committed_bytes();
Erik Helin604a75f2013-06-26 16:58:37 +0200292 return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
293}
294
295size_t MetaspacePool::used_in_bytes() {
Erik Helin977d1f72014-03-31 17:09:38 +0200296 return MetaspaceAux::used_bytes();
Erik Helin604a75f2013-06-26 16:58:37 +0200297}
298
Erik Helin604a75f2013-06-26 16:58:37 +0200299size_t MetaspacePool::calculate_max_size() const {
Erik Helin2cab7ea2013-09-17 20:59:07 +0200300 return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize :
301 MemoryUsage::undefined_size();
Erik Helin604a75f2013-06-26 16:58:37 +0200302}
303
304CompressedKlassSpacePool::CompressedKlassSpacePool() :
Erik Helin2cab7ea2013-09-17 20:59:07 +0200305 MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { }
Erik Helin604a75f2013-06-26 16:58:37 +0200306
307size_t CompressedKlassSpacePool::used_in_bytes() {
Erik Helin977d1f72014-03-31 17:09:38 +0200308 return MetaspaceAux::used_bytes(Metaspace::ClassType);
Erik Helin604a75f2013-06-26 16:58:37 +0200309}
310
Erik Helin604a75f2013-06-26 16:58:37 +0200311MemoryUsage CompressedKlassSpacePool::get_memory_usage() {
Erik Helin2cab7ea2013-09-17 20:59:07 +0200312 size_t committed = MetaspaceAux::committed_bytes(Metaspace::ClassType);
Erik Helin604a75f2013-06-26 16:58:37 +0200313 return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
314}