author | zgu |
Mon, 17 Sep 2012 16:37:26 -0400 | |
changeset 13861 | 619cff4bfb8b |
parent 13859 | 7fe4578493fc |
child 13975 | 2f7431485cfa |
permissions | -rw-r--r-- |
13195 | 1 |
/* |
2 |
* Copyright (c) 2012, 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 |
*/ |
|
24 |
||
25 |
#ifndef SHARE_VM_SERVICES_MEM_TRACKER_HPP |
|
26 |
#define SHARE_VM_SERVICES_MEM_TRACKER_HPP |
|
27 |
||
28 |
#include "memory/allocation.hpp" |
|
29 |
#include "runtime/globals.hpp" |
|
30 |
#include "runtime/mutex.hpp" |
|
31 |
#include "runtime/os.hpp" |
|
32 |
#include "runtime/thread.hpp" |
|
33 |
#include "services/memPtr.hpp" |
|
34 |
#include "services/memRecorder.hpp" |
|
35 |
#include "services/memSnapshot.hpp" |
|
36 |
#include "services/memTrackWorker.hpp" |
|
37 |
||
38 |
#ifdef SOLARIS |
|
39 |
#include "thread_solaris.inline.hpp" |
|
40 |
#endif |
|
41 |
||
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
42 |
#ifdef _DEBUG |
13195 | 43 |
#define DEBUG_CALLER_PC os::get_caller_pc(3) |
44 |
#else |
|
45 |
#define DEBUG_CALLER_PC 0 |
|
46 |
#endif |
|
47 |
||
48 |
// The thread closure walks threads to collect per-thread |
|
49 |
// memory recorders at NMT sync point |
|
50 |
class SyncThreadRecorderClosure : public ThreadClosure { |
|
51 |
private: |
|
52 |
int _thread_count; |
|
53 |
||
54 |
public: |
|
55 |
SyncThreadRecorderClosure() { |
|
56 |
_thread_count =0; |
|
57 |
} |
|
58 |
||
59 |
void do_thread(Thread* thread); |
|
60 |
int get_thread_count() const { |
|
61 |
return _thread_count; |
|
62 |
} |
|
63 |
}; |
|
64 |
||
65 |
class BaselineOutputer; |
|
66 |
class MemSnapshot; |
|
67 |
class MemTrackWorker; |
|
68 |
class Thread; |
|
69 |
/* |
|
70 |
* MemTracker is the 'gate' class to native memory tracking runtime. |
|
71 |
*/ |
|
72 |
class MemTracker : AllStatic { |
|
73 |
friend class MemTrackWorker; |
|
74 |
friend class MemSnapshot; |
|
75 |
friend class SyncThreadRecorderClosure; |
|
76 |
||
77 |
// NMT state |
|
78 |
enum NMTStates { |
|
79 |
NMT_uninited, // not yet initialized |
|
80 |
NMT_bootstrapping_single_thread, // bootstrapping, VM is in single thread mode |
|
81 |
NMT_bootstrapping_multi_thread, // bootstrapping, VM is about to enter multi-thread mode |
|
82 |
NMT_started, // NMT fully started |
|
83 |
NMT_shutdown_pending, // shutdown pending |
|
84 |
NMT_final_shutdown, // in final phase of shutdown |
|
85 |
NMT_shutdown // shutdown |
|
86 |
}; |
|
87 |
||
13861
619cff4bfb8b
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
13859
diff
changeset
|
88 |
public: |
13195 | 89 |
// native memory tracking level |
90 |
enum NMTLevel { |
|
91 |
NMT_off, // native memory tracking is off |
|
92 |
NMT_summary, // don't track callsite |
|
93 |
NMT_detail // track callsite also |
|
94 |
}; |
|
95 |
||
96 |
enum ShutdownReason { |
|
97 |
NMT_shutdown_none, // no shutdown requested |
|
98 |
NMT_shutdown_user, // user requested shutdown |
|
99 |
NMT_normal, // normal shutdown, process exit |
|
100 |
NMT_out_of_memory, // shutdown due to out of memory |
|
101 |
NMT_initialization, // shutdown due to initialization failure |
|
102 |
NMT_use_malloc_only, // can not combine NMT with UseMallocOnly flag |
|
103 |
NMT_error_reporting, // shutdown by vmError::report_and_die() |
|
104 |
NMT_out_of_generation, // running out of generation queue |
|
105 |
NMT_sequence_overflow // overflow the sequence number |
|
106 |
}; |
|
107 |
||
108 |
public: |
|
109 |
// initialize NMT tracking level from command line options, called |
|
110 |
// from VM command line parsing code |
|
111 |
static void init_tracking_options(const char* option_line); |
|
112 |
||
113 |
// if NMT is enabled to record memory activities |
|
114 |
static inline bool is_on() { |
|
115 |
return (_tracking_level >= NMT_summary && |
|
116 |
_state >= NMT_bootstrapping_single_thread); |
|
117 |
} |
|
118 |
||
13861
619cff4bfb8b
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
13859
diff
changeset
|
119 |
static inline enum NMTLevel tracking_level() { |
619cff4bfb8b
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
13859
diff
changeset
|
120 |
return _tracking_level; |
619cff4bfb8b
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
13859
diff
changeset
|
121 |
} |
619cff4bfb8b
7188594: Print statistic collected by NMT with VM flag
zgu
parents:
13859
diff
changeset
|
122 |
|
13195 | 123 |
// user readable reason for shutting down NMT |
124 |
static const char* reason() { |
|
125 |
switch(_reason) { |
|
126 |
case NMT_shutdown_none: |
|
127 |
return "Native memory tracking is not enabled"; |
|
128 |
case NMT_shutdown_user: |
|
129 |
return "Native memory tracking has been shutdown by user"; |
|
130 |
case NMT_normal: |
|
131 |
return "Native memory tracking has been shutdown due to process exiting"; |
|
13301
f6dd749390dd
7181986: NMT ON: Assertion failure when running jdi ExpiredRequestDeletionTest
zgu
parents:
13195
diff
changeset
|
132 |
case NMT_out_of_memory: |
f6dd749390dd
7181986: NMT ON: Assertion failure when running jdi ExpiredRequestDeletionTest
zgu
parents:
13195
diff
changeset
|
133 |
return "Native memory tracking has been shutdown due to out of native memory"; |
13195 | 134 |
case NMT_initialization: |
135 |
return "Native memory tracking failed to initialize"; |
|
136 |
case NMT_error_reporting: |
|
137 |
return "Native memory tracking has been shutdown due to error reporting"; |
|
138 |
case NMT_out_of_generation: |
|
139 |
return "Native memory tracking has been shutdown due to running out of generation buffer"; |
|
140 |
case NMT_sequence_overflow: |
|
141 |
return "Native memory tracking has been shutdown due to overflow the sequence number"; |
|
142 |
case NMT_use_malloc_only: |
|
143 |
return "Native memory tracking is not supported when UseMallocOnly is on"; |
|
144 |
default: |
|
145 |
ShouldNotReachHere(); |
|
146 |
return NULL; |
|
147 |
} |
|
148 |
} |
|
149 |
||
150 |
// test if we can walk native stack |
|
151 |
static bool can_walk_stack() { |
|
152 |
// native stack is not walkable during bootstrapping on sparc |
|
153 |
#if defined(SPARC) |
|
154 |
return (_state == NMT_started); |
|
155 |
#else |
|
156 |
return (_state >= NMT_bootstrapping_single_thread && _state <= NMT_started); |
|
157 |
#endif |
|
158 |
} |
|
159 |
||
160 |
// if native memory tracking tracks callsite |
|
161 |
static inline bool track_callsite() { return _tracking_level == NMT_detail; } |
|
162 |
||
163 |
// shutdown native memory tracking capability. Native memory tracking |
|
164 |
// can be shutdown by VM when it encounters low memory scenarios. |
|
165 |
// Memory tracker should gracefully shutdown itself, and preserve the |
|
166 |
// latest memory statistics for post morten diagnosis. |
|
167 |
static void shutdown(ShutdownReason reason); |
|
168 |
||
169 |
// if there is shutdown requested |
|
170 |
static inline bool shutdown_in_progress() { |
|
171 |
return (_state >= NMT_shutdown_pending); |
|
172 |
} |
|
173 |
||
174 |
// bootstrap native memory tracking, so it can start to collect raw data |
|
175 |
// before worker thread can start |
|
176 |
||
177 |
// the first phase of bootstrapping, when VM still in single-threaded mode |
|
178 |
static void bootstrap_single_thread(); |
|
179 |
// the second phase of bootstrapping, VM is about or already in multi-threaded mode |
|
180 |
static void bootstrap_multi_thread(); |
|
181 |
||
182 |
||
183 |
// start() has to be called when VM still in single thread mode, but after |
|
184 |
// command line option parsing is done. |
|
185 |
static void start(); |
|
186 |
||
187 |
// record a 'malloc' call |
|
188 |
static inline void record_malloc(address addr, size_t size, MEMFLAGS flags, |
|
189 |
address pc = 0, Thread* thread = NULL) { |
|
190 |
if (NMT_CAN_TRACK(flags)) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
191 |
assert(size > 0, "Sanity check"); |
13195 | 192 |
create_memory_record(addr, (flags|MemPointerRecord::malloc_tag()), size, pc, thread); |
193 |
} |
|
194 |
} |
|
195 |
// record a 'free' call |
|
196 |
static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) { |
|
197 |
if (is_on() && NMT_CAN_TRACK(flags)) { |
|
198 |
create_memory_record(addr, MemPointerRecord::free_tag(), 0, 0, thread); |
|
199 |
} |
|
200 |
} |
|
201 |
// record a 'realloc' call |
|
202 |
static inline void record_realloc(address old_addr, address new_addr, size_t size, |
|
203 |
MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { |
|
204 |
if (is_on()) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
205 |
assert(size > 0, "Sanity check"); |
13195 | 206 |
record_free(old_addr, flags, thread); |
207 |
record_malloc(new_addr, size, flags, pc, thread); |
|
208 |
} |
|
209 |
} |
|
210 |
||
211 |
// record arena size |
|
212 |
static inline void record_arena_size(address addr, size_t size) { |
|
213 |
// we add a positive offset to arena address, so we can have arena size record |
|
214 |
// sorted after arena record |
|
215 |
if (is_on() && !UseMallocOnly) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
216 |
assert(addr != NULL, "Sanity check"); |
13195 | 217 |
create_memory_record((addr + sizeof(void*)), MemPointerRecord::arena_size_tag(), size, |
218 |
0, NULL); |
|
219 |
} |
|
220 |
} |
|
221 |
||
222 |
// record a virtual memory 'reserve' call |
|
223 |
static inline void record_virtual_memory_reserve(address addr, size_t size, |
|
224 |
address pc = 0, Thread* thread = NULL) { |
|
225 |
if (is_on()) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
226 |
assert(size > 0, "Sanity check"); |
13195 | 227 |
create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag(), |
228 |
size, pc, thread); |
|
229 |
} |
|
230 |
} |
|
231 |
||
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
232 |
static inline void record_thread_stack(address addr, size_t size, Thread* thr, |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
233 |
address pc = 0) { |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
234 |
if (is_on()) { |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
235 |
assert(size > 0 && thr != NULL, "Sanity check"); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
236 |
create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag() | mtThreadStack, |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
237 |
size, pc, thr); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
238 |
create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag() | mtThreadStack, |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
239 |
size, pc, thr); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
240 |
} |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
241 |
} |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
242 |
|
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
243 |
static inline void release_thread_stack(address addr, size_t size, Thread* thr) { |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
244 |
if (is_on()) { |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
245 |
assert(size > 0 && thr != NULL, "Sanity check"); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
246 |
create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag() | mtThreadStack, |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
247 |
size, DEBUG_CALLER_PC, thr); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
248 |
create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag() | mtThreadStack, |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
249 |
size, DEBUG_CALLER_PC, thr); |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
250 |
} |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
251 |
} |
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
252 |
|
13195 | 253 |
// record a virtual memory 'commit' call |
254 |
static inline void record_virtual_memory_commit(address addr, size_t size, |
|
255 |
address pc = 0, Thread* thread = NULL) { |
|
256 |
if (is_on()) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
257 |
assert(size > 0, "Sanity check"); |
13195 | 258 |
create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag(), |
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
259 |
size, DEBUG_CALLER_PC, thread); |
13195 | 260 |
} |
261 |
} |
|
262 |
||
263 |
// record a virtual memory 'uncommit' call |
|
264 |
static inline void record_virtual_memory_uncommit(address addr, size_t size, |
|
265 |
Thread* thread = NULL) { |
|
266 |
if (is_on()) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
267 |
assert(size > 0, "Sanity check"); |
13195 | 268 |
create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag(), |
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
269 |
size, DEBUG_CALLER_PC, thread); |
13195 | 270 |
} |
271 |
} |
|
272 |
||
273 |
// record a virtual memory 'release' call |
|
274 |
static inline void record_virtual_memory_release(address addr, size_t size, |
|
275 |
Thread* thread = NULL) { |
|
276 |
if (is_on()) { |
|
13859
7fe4578493fc
7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents:
13744
diff
changeset
|
277 |
assert(size > 0, "Sanity check"); |
13195 | 278 |
create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag(), |
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
279 |
size, DEBUG_CALLER_PC, thread); |
13195 | 280 |
} |
281 |
} |
|
282 |
||
283 |
// record memory type on virtual memory base address |
|
284 |
static inline void record_virtual_memory_type(address base, MEMFLAGS flags, |
|
285 |
Thread* thread = NULL) { |
|
286 |
if (is_on()) { |
|
287 |
assert(base > 0, "wrong base address"); |
|
288 |
assert((flags & (~mt_masks)) == 0, "memory type only"); |
|
289 |
create_memory_record(base, (flags | MemPointerRecord::virtual_memory_type_tag()), |
|
13744
631fe815def5
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
13470
diff
changeset
|
290 |
0, DEBUG_CALLER_PC, thread); |
13195 | 291 |
} |
292 |
} |
|
293 |
||
294 |
||
295 |
// create memory baseline of current memory snapshot |
|
296 |
static bool baseline(); |
|
297 |
// is there a memory baseline |
|
298 |
static bool has_baseline() { |
|
299 |
return _baseline.baselined(); |
|
300 |
} |
|
301 |
||
302 |
// print memory usage from current snapshot |
|
303 |
static bool print_memory_usage(BaselineOutputer& out, size_t unit, |
|
304 |
bool summary_only = true); |
|
305 |
// compare memory usage between current snapshot and baseline |
|
306 |
static bool compare_memory_usage(BaselineOutputer& out, size_t unit, |
|
307 |
bool summary_only = true); |
|
308 |
||
309 |
// sync is called within global safepoint to synchronize nmt data |
|
310 |
static void sync(); |
|
311 |
||
312 |
// called when a thread is about to exit |
|
313 |
static void thread_exiting(JavaThread* thread); |
|
314 |
||
315 |
// retrieve global snapshot |
|
316 |
static MemSnapshot* get_snapshot() { |
|
317 |
if (shutdown_in_progress()) { |
|
318 |
return NULL; |
|
319 |
} |
|
320 |
return _snapshot; |
|
321 |
} |
|
322 |
||
323 |
// print tracker stats |
|
324 |
NOT_PRODUCT(static void print_tracker_stats(outputStream* st);) |
|
325 |
NOT_PRODUCT(static void walk_stack(int toSkip, char* buf, int len);) |
|
326 |
||
327 |
private: |
|
328 |
// start native memory tracking worker thread |
|
329 |
static bool start_worker(); |
|
330 |
||
331 |
// called by worker thread to complete shutdown process |
|
332 |
static void final_shutdown(); |
|
333 |
||
334 |
protected: |
|
335 |
// retrieve per-thread recorder of the specified thread. |
|
336 |
// if the recorder is full, it will be enqueued to overflow |
|
337 |
// queue, a new recorder is acquired from recorder pool or a |
|
338 |
// new instance is created. |
|
339 |
// when thread == NULL, it means global recorder |
|
340 |
static MemRecorder* get_thread_recorder(JavaThread* thread); |
|
341 |
||
342 |
// per-thread recorder pool |
|
343 |
static void release_thread_recorder(MemRecorder* rec); |
|
344 |
static void delete_all_pooled_recorders(); |
|
345 |
||
346 |
// pending recorder queue. Recorders are queued to pending queue |
|
347 |
// when they are overflowed or collected at nmt sync point. |
|
348 |
static void enqueue_pending_recorder(MemRecorder* rec); |
|
349 |
static MemRecorder* get_pending_recorders(); |
|
350 |
static void delete_all_pending_recorders(); |
|
351 |
||
352 |
private: |
|
353 |
// retrieve a pooled memory record or create new one if there is not |
|
354 |
// one available |
|
355 |
static MemRecorder* get_new_or_pooled_instance(); |
|
356 |
static void create_memory_record(address addr, MEMFLAGS type, |
|
357 |
size_t size, address pc, Thread* thread); |
|
358 |
static void create_record_in_recorder(address addr, MEMFLAGS type, |
|
13300 | 359 |
size_t size, address pc, JavaThread* thread); |
13195 | 360 |
|
361 |
private: |
|
362 |
// global memory snapshot |
|
363 |
static MemSnapshot* _snapshot; |
|
364 |
||
365 |
// a memory baseline of snapshot |
|
366 |
static MemBaseline _baseline; |
|
367 |
||
368 |
// query lock |
|
13301
f6dd749390dd
7181986: NMT ON: Assertion failure when running jdi ExpiredRequestDeletionTest
zgu
parents:
13195
diff
changeset
|
369 |
static Mutex* _query_lock; |
13195 | 370 |
|
371 |
// a thread can start to allocate memory before it is attached |
|
372 |
// to VM 'Thread', those memory activities are recorded here. |
|
373 |
// ThreadCritical is required to guard this global recorder. |
|
374 |
static MemRecorder* _global_recorder; |
|
375 |
||
376 |
// main thread id |
|
377 |
debug_only(static intx _main_thread_tid;) |
|
378 |
||
379 |
// pending recorders to be merged |
|
380 |
static volatile MemRecorder* _merge_pending_queue; |
|
381 |
||
382 |
NOT_PRODUCT(static volatile jint _pending_recorder_count;) |
|
383 |
||
384 |
// pooled memory recorders |
|
385 |
static volatile MemRecorder* _pooled_recorders; |
|
386 |
||
387 |
// memory recorder pool management, uses following |
|
388 |
// counter to determine if a released memory recorder |
|
389 |
// should be pooled |
|
390 |
||
391 |
// latest thread count |
|
392 |
static int _thread_count; |
|
393 |
// pooled recorder count |
|
394 |
static volatile jint _pooled_recorder_count; |
|
395 |
||
396 |
||
397 |
// worker thread to merge pending recorders into snapshot |
|
398 |
static MemTrackWorker* _worker_thread; |
|
399 |
||
400 |
// how many safepoints we skipped without entering sync point |
|
401 |
static int _sync_point_skip_count; |
|
402 |
||
403 |
// if the tracker is properly intialized |
|
404 |
static bool _is_tracker_ready; |
|
405 |
// tracking level (off, summary and detail) |
|
406 |
static enum NMTLevel _tracking_level; |
|
407 |
||
408 |
// current nmt state |
|
409 |
static volatile enum NMTStates _state; |
|
410 |
// the reason for shutting down nmt |
|
411 |
static enum ShutdownReason _reason; |
|
412 |
}; |
|
413 |
||
414 |
#endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP |