src/share/vm/jfr/periodic/jfrPeriodic.cpp

changeset 9858
b985cbb00e68
child 9872
8d15befeab20
equal deleted inserted replaced
9727:c7a3e57fdf4a 9858:b985cbb00e68
1 /*
2 * Copyright (c) 2012, 2018, 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 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/classLoaderStats.hpp"
28 #include "classfile/javaClasses.hpp"
29 #include "code/codeCache.hpp"
30 #include "compiler/compileBroker.hpp"
31 #include "gc_implementation/g1/g1HeapRegionEventSender.hpp"
32 #include "gc_implementation/shared/gcConfiguration.hpp"
33 #include "gc_implementation/shared/gcTrace.hpp"
34 #include "gc_implementation/shared/objectCountEventSender.hpp"
35 #include "gc_implementation/shared/vmGCOperations.hpp"
36 #include "jfr/jfrEvents.hpp"
37 #include "jfr/periodic/jfrOSInterface.hpp"
38 #include "jfr/periodic/jfrThreadCPULoadEvent.hpp"
39 #include "jfr/periodic/jfrThreadDumpEvent.hpp"
40 #include "jfr/periodic/jfrNetworkUtilization.hpp"
41 #include "jfr/recorder/jfrRecorder.hpp"
42 #include "jfr/support/jfrThreadId.hpp"
43 #include "jfr/utilities/jfrTime.hpp"
44 #include "jfrfiles/jfrPeriodic.hpp"
45 #include "memory/heapInspection.hpp"
46 #include "memory/resourceArea.hpp"
47 #include "oops/oop.inline.hpp"
48 #include "runtime/arguments.hpp"
49 #include "runtime/globals.hpp"
50 #include "runtime/os.hpp"
51 #include "runtime/os_perf.hpp"
52 #include "runtime/thread.inline.hpp"
53 #include "runtime/sweeper.hpp"
54 #include "runtime/vmThread.hpp"
55 #include "services/classLoadingService.hpp"
56 #include "services/management.hpp"
57 #include "services/threadService.hpp"
58 #include "utilities/exceptions.hpp"
59 #include "utilities/globalDefinitions.hpp"
60
61 /**
62 * JfrPeriodic class
63 * Implementation of declarations in
64 * xsl generated traceRequestables.hpp
65 */
66 #define TRACE_REQUEST_FUNC(id) void JfrPeriodicEventSet::request##id(void)
67
68 TRACE_REQUEST_FUNC(JVMInformation) {
69 ResourceMark rm;
70 EventJVMInformation event;
71 event.set_jvmName(VM_Version::vm_name());
72 event.set_jvmVersion(VM_Version::internal_vm_info_string());
73 event.set_javaArguments(Arguments::java_command());
74 event.set_jvmArguments(Arguments::jvm_args());
75 event.set_jvmFlags(Arguments::jvm_flags());
76 event.set_jvmStartTime(Management::vm_init_done_time());
77 event.commit();
78 }
79
80 TRACE_REQUEST_FUNC(OSInformation) {
81 ResourceMark rm;
82 char* os_name = NEW_RESOURCE_ARRAY(char, 2048);
83 JfrOSInterface::os_version(&os_name);
84 EventOSInformation event;
85 event.set_osVersion(os_name);
86 event.commit();
87 }
88
89 /*
90 * This is left empty on purpose, having ExecutionSample as a requestable
91 * is a way of getting the period. The period is passed to ThreadSampling::update_period.
92 * Implementation in jfrSamples.cpp
93 */
94 TRACE_REQUEST_FUNC(ExecutionSample) {
95 }
96 TRACE_REQUEST_FUNC(NativeMethodSample) {
97 }
98
99 TRACE_REQUEST_FUNC(ThreadDump) {
100 ResourceMark rm;
101 EventThreadDump event;
102 event.set_result(JfrDcmdEvent::thread_dump());
103 event.commit();
104 }
105
106 static int _native_library_callback(const char* name, address base, address top, void *param) {
107 EventNativeLibrary event(UNTIMED);
108 event.set_name(name);
109 event.set_baseAddress((u8)base);
110 event.set_topAddress((u8)top);
111 event.set_endtime(*(JfrTicks*) param);
112 event.commit();
113 return 0;
114 }
115
116 TRACE_REQUEST_FUNC(NativeLibrary) {
117 JfrTicks ts= JfrTicks::now();
118 os::get_loaded_modules_info(&_native_library_callback, (void *)&ts);
119 }
120
121 TRACE_REQUEST_FUNC(InitialEnvironmentVariable) {
122 JfrOSInterface::generate_initial_environment_variable_events();
123 }
124
125 TRACE_REQUEST_FUNC(CPUInformation) {
126 CPUInformation cpu_info;
127 int ret_val = JfrOSInterface::cpu_information(cpu_info);
128 if (ret_val == OS_ERR) {
129 if (LogJFR) tty->print_cr( "Unable to generate requestable event CPUInformation");
130 return;
131 }
132 if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {
133 return;
134 }
135 if (ret_val == OS_OK) {
136 EventCPUInformation event;
137 event.set_cpu(cpu_info.cpu_name());
138 event.set_description(cpu_info.cpu_description());
139 event.set_sockets(cpu_info.number_of_sockets());
140 event.set_cores(cpu_info.number_of_cores());
141 event.set_hwThreads(cpu_info.number_of_hardware_threads());
142 event.commit();
143 }
144 }
145
146 TRACE_REQUEST_FUNC(CPULoad) {
147 double u = 0; // user time
148 double s = 0; // kernel time
149 double t = 0; // total time
150 int ret_val = JfrOSInterface::cpu_loads_process(&u, &s, &t);
151 if (ret_val == OS_ERR) {
152 if (LogJFR) tty->print_cr( "Unable to generate requestable event CPULoad");
153 return;
154 }
155 if (ret_val == OS_OK) {
156 EventCPULoad event;
157 event.set_jvmUser((float)u);
158 event.set_jvmSystem((float)s);
159 event.set_machineTotal((float)t);
160 event.commit();
161 }
162 }
163
164 TRACE_REQUEST_FUNC(ThreadCPULoad) {
165 JfrThreadCPULoadEvent::send_events();
166 }
167
168 TRACE_REQUEST_FUNC(NetworkUtilization) {
169 JfrNetworkUtilization::send_events();
170 }
171
172 TRACE_REQUEST_FUNC(CPUTimeStampCounter) {
173 EventCPUTimeStampCounter event;
174 event.set_fastTimeEnabled(JfrTime::is_ft_enabled());
175 event.set_fastTimeAutoEnabled(JfrTime::is_ft_supported());
176 event.set_osFrequency(os::elapsed_frequency());
177 event.set_fastTimeFrequency(JfrTime::frequency());
178 event.commit();
179 }
180
181 TRACE_REQUEST_FUNC(SystemProcess) {
182 char pid_buf[16];
183 SystemProcess* processes = NULL;
184 int num_of_processes = 0;
185 JfrTicks start_time = JfrTicks::now();
186 int ret_val = JfrOSInterface::system_processes(&processes, &num_of_processes);
187 if (ret_val == OS_ERR) {
188 if (LogJFR) tty->print_cr( "Unable to generate requestable event SystemProcesses");
189 return;
190 }
191 JfrTicks end_time = JfrTicks::now();
192 if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {
193 return;
194 }
195 if (ret_val == OS_OK) {
196 // feature is implemented, write real event
197 while (processes != NULL) {
198 SystemProcess* tmp = processes;
199 const char* info = processes->command_line();
200 if (info == NULL) {
201 info = processes->path();
202 }
203 if (info == NULL) {
204 info = processes->name();
205 }
206 if (info == NULL) {
207 info = "?";
208 }
209 jio_snprintf(pid_buf, sizeof(pid_buf), "%d", processes->pid());
210 EventSystemProcess event(UNTIMED);
211 event.set_pid(pid_buf);
212 event.set_commandLine(info);
213 event.set_starttime(start_time);
214 event.set_endtime(end_time);
215 event.commit();
216 processes = processes->next();
217 delete tmp;
218 }
219 }
220 }
221
222 TRACE_REQUEST_FUNC(ThreadContextSwitchRate) {
223 double rate = 0.0;
224 int ret_val = JfrOSInterface::context_switch_rate(&rate);
225 if (ret_val == OS_ERR) {
226 if (LogJFR) tty->print_cr( "Unable to generate requestable event ThreadContextSwitchRate");
227 return;
228 }
229 if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {
230 return;
231 }
232 if (ret_val == OS_OK) {
233 EventThreadContextSwitchRate event;
234 event.set_switchRate((float)rate + 0.0f);
235 event.commit();
236 }
237 }
238
239 #define SEND_FLAGS_OF_TYPE(eventType, flagType) \
240 do { \
241 Flag *flag = Flag::flags; \
242 while (flag->_name != NULL) { \
243 if (flag->is_ ## flagType()) { \
244 if (flag->is_unlocked()) { \
245 Event ## eventType event; \
246 event.set_name(flag->_name); \
247 event.set_value(flag->get_ ## flagType()); \
248 event.set_origin(flag->get_origin()); \
249 event.commit(); \
250 } \
251 } \
252 ++flag; \
253 } \
254 } while (0)
255
256 TRACE_REQUEST_FUNC(IntFlag) {
257 SEND_FLAGS_OF_TYPE(IntFlag, intx);
258 }
259
260 TRACE_REQUEST_FUNC(UnsignedIntFlag) {
261 SEND_FLAGS_OF_TYPE(UnsignedIntFlag, uintx);
262 }
263
264 TRACE_REQUEST_FUNC(LongFlag) {
265 SEND_FLAGS_OF_TYPE(LongFlag, intx);
266 }
267
268 TRACE_REQUEST_FUNC(UnsignedLongFlag) {
269 SEND_FLAGS_OF_TYPE(UnsignedLongFlag, uintx);
270 SEND_FLAGS_OF_TYPE(UnsignedLongFlag, uint64_t);
271 }
272
273 TRACE_REQUEST_FUNC(DoubleFlag) {
274 SEND_FLAGS_OF_TYPE(DoubleFlag, double);
275 }
276
277 TRACE_REQUEST_FUNC(BooleanFlag) {
278 SEND_FLAGS_OF_TYPE(BooleanFlag, bool);
279 }
280
281 TRACE_REQUEST_FUNC(StringFlag) {
282 SEND_FLAGS_OF_TYPE(StringFlag, ccstr);
283 }
284
285 class VM_GC_SendObjectCountEvent : public VM_GC_HeapInspection {
286 public:
287 VM_GC_SendObjectCountEvent() : VM_GC_HeapInspection(NULL, true) {}
288 virtual void doit() {
289 ObjectCountEventSender::enable_requestable_event();
290 collect();
291 ObjectCountEventSender::disable_requestable_event();
292 }
293 };
294
295 TRACE_REQUEST_FUNC(ObjectCount) {
296 VM_GC_SendObjectCountEvent op;
297 VMThread::execute(&op);
298 }
299
300 class VM_G1SendHeapRegionInfoEvents : public VM_Operation {
301 virtual void doit() {
302 G1HeapRegionEventSender::send_events();
303 }
304 virtual VMOp_Type type() const { return VMOp_HeapIterateOperation; }
305 };
306
307 TRACE_REQUEST_FUNC(G1HeapRegionInformation) {
308 if (UseG1GC) {
309 VM_G1SendHeapRegionInfoEvents op;
310 VMThread::execute(&op);
311 }
312 }
313
314 // Java Mission Control (JMC) uses (Java) Long.MIN_VALUE to describe that a
315 // long value is undefined.
316 static jlong jmc_undefined_long = min_jlong;
317
318 TRACE_REQUEST_FUNC(GCConfiguration) {
319 GCConfiguration conf;
320 jlong pause_target = conf.has_pause_target_default_value() ? jmc_undefined_long : conf.pause_target();
321 EventGCConfiguration event;
322 event.set_youngCollector(conf.young_collector());
323 event.set_oldCollector(conf.old_collector());
324 event.set_parallelGCThreads(conf.num_parallel_gc_threads());
325 event.set_concurrentGCThreads(conf.num_concurrent_gc_threads());
326 event.set_usesDynamicGCThreads(conf.uses_dynamic_gc_threads());
327 event.set_isExplicitGCConcurrent(conf.is_explicit_gc_concurrent());
328 event.set_isExplicitGCDisabled(conf.is_explicit_gc_disabled());
329 event.set_gcTimeRatio(conf.gc_time_ratio());
330 event.set_pauseTarget((s8)pause_target);
331 event.commit();
332 }
333
334 TRACE_REQUEST_FUNC(GCTLABConfiguration) {
335 GCTLABConfiguration conf;
336 EventGCTLABConfiguration event;
337 event.set_usesTLABs(conf.uses_tlabs());
338 event.set_minTLABSize(conf.min_tlab_size());
339 event.set_tlabRefillWasteLimit(conf.tlab_refill_waste_limit());
340 event.commit();
341 }
342
343 TRACE_REQUEST_FUNC(GCSurvivorConfiguration) {
344 GCSurvivorConfiguration conf;
345 EventGCSurvivorConfiguration event;
346 event.set_maxTenuringThreshold(conf.max_tenuring_threshold());
347 event.set_initialTenuringThreshold(conf.initial_tenuring_threshold());
348 event.commit();
349 }
350
351 TRACE_REQUEST_FUNC(GCHeapConfiguration) {
352 GCHeapConfiguration conf;
353 EventGCHeapConfiguration event;
354 event.set_minSize(conf.min_size());
355 event.set_maxSize(conf.max_size());
356 event.set_initialSize(conf.initial_size());
357 event.set_usesCompressedOops(conf.uses_compressed_oops());
358 event.set_compressedOopsMode(conf.narrow_oop_mode());
359 event.set_objectAlignment(conf.object_alignment_in_bytes());
360 event.set_heapAddressBits(conf.heap_address_size_in_bits());
361 event.commit();
362 }
363
364 TRACE_REQUEST_FUNC(YoungGenerationConfiguration) {
365 GCYoungGenerationConfiguration conf;
366 jlong max_size = conf.has_max_size_default_value() ? jmc_undefined_long : conf.max_size();
367 EventYoungGenerationConfiguration event;
368 event.set_maxSize((u8)max_size);
369 event.set_minSize(conf.min_size());
370 event.set_newRatio(conf.new_ratio());
371 event.commit();
372 }
373
374 TRACE_REQUEST_FUNC(InitialSystemProperty) {
375 SystemProperty* p = Arguments::system_properties();
376 JfrTicks time_stamp = JfrTicks::now();
377 while (p != NULL) {
378 if (true/* XXX fix me if you want !p->internal()*/) {
379 EventInitialSystemProperty event(UNTIMED);
380 event.set_key(p->key());
381 event.set_value(p->value());
382 event.set_endtime(time_stamp);
383 event.commit();
384 }
385 p = p->next();
386 }
387 }
388
389 TRACE_REQUEST_FUNC(ThreadAllocationStatistics) {
390 ResourceMark rm;
391 int initial_size = Threads::number_of_threads();
392 GrowableArray<jlong> allocated(initial_size);
393 GrowableArray<traceid> thread_ids(initial_size);
394 JfrTicks time_stamp = JfrTicks::now();
395 {
396 // Collect allocation statistics while holding threads lock
397 MutexLockerEx ml(Threads_lock);
398 for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
399 allocated.append(thread->cooked_allocated_bytes());
400 thread_ids.append(JFR_THREAD_ID(thread));
401 }
402 }
403
404 // Write allocation statistics to buffer.
405 for(int i = 0; i < thread_ids.length(); i++) {
406 EventThreadAllocationStatistics event(UNTIMED);
407 event.set_allocated(allocated.at(i));
408 event.set_thread(thread_ids.at(i));
409 event.set_endtime(time_stamp);
410 event.commit();
411 }
412 }
413
414 /**
415 * PhysicalMemory event represents:
416 *
417 * @totalSize == The amount of physical memory (hw) installed and reported by the OS, in bytes.
418 * @usedSize == The amount of physical memory currently in use in the system (reserved/committed), in bytes.
419 *
420 * Both fields are systemwide, i.e. represents the entire OS/HW environment.
421 * These fields do not include virtual memory.
422 *
423 * If running inside a guest OS on top of a hypervisor in a virtualized environment,
424 * the total memory reported is the amount of memory configured for the guest OS by the hypervisor.
425 */
426 TRACE_REQUEST_FUNC(PhysicalMemory) {
427 u8 totalPhysicalMemory = os::physical_memory();
428 EventPhysicalMemory event;
429 event.set_totalSize(totalPhysicalMemory);
430 event.set_usedSize(totalPhysicalMemory - os::available_memory());
431 event.commit();
432 }
433
434 TRACE_REQUEST_FUNC(JavaThreadStatistics) {
435 EventJavaThreadStatistics event;
436 event.set_activeCount(ThreadService::get_live_thread_count());
437 event.set_daemonCount(ThreadService::get_daemon_thread_count());
438 event.set_accumulatedCount(ThreadService::get_total_thread_count());
439 event.set_peakCount(ThreadService::get_peak_thread_count());
440 event.commit();
441 }
442
443 TRACE_REQUEST_FUNC(ClassLoadingStatistics) {
444 EventClassLoadingStatistics event;
445 event.set_loadedClassCount(ClassLoadingService::loaded_class_count());
446 event.set_unloadedClassCount(ClassLoadingService::unloaded_class_count());
447 event.commit();
448 }
449
450 class JfrClassLoaderStatsClosure : public ClassLoaderStatsClosure {
451 public:
452 JfrClassLoaderStatsClosure() : ClassLoaderStatsClosure(NULL) {}
453
454 bool do_entry(oop const& key, ClassLoaderStats* const& cls) {
455 const ClassLoaderData* this_cld = cls->_class_loader != NULL ?
456 java_lang_ClassLoader::loader_data(cls->_class_loader) : (ClassLoaderData*)NULL;
457 const ClassLoaderData* parent_cld = cls->_parent != NULL ?
458 java_lang_ClassLoader::loader_data(cls->_parent) : (ClassLoaderData*)NULL;
459 EventClassLoaderStatistics event;
460 event.set_classLoader(this_cld);
461 event.set_parentClassLoader(parent_cld);
462 event.set_classLoaderData((intptr_t)cls->_cld);
463 event.set_classCount(cls->_classes_count);
464 event.set_chunkSize(cls->_chunk_sz);
465 event.set_blockSize(cls->_block_sz);
466 event.set_anonymousClassCount(cls->_anon_classes_count);
467 event.set_anonymousChunkSize(cls->_anon_chunk_sz);
468 event.set_anonymousBlockSize(cls->_anon_block_sz);
469 event.commit();
470 return true;
471 }
472
473 void createEvents(void) {
474 _stats->iterate(this);
475 }
476 };
477
478 class JfrClassLoaderStatsVMOperation : public ClassLoaderStatsVMOperation {
479 public:
480 JfrClassLoaderStatsVMOperation() : ClassLoaderStatsVMOperation(NULL) { }
481
482 void doit() {
483 JfrClassLoaderStatsClosure clsc;
484 ClassLoaderDataGraph::cld_do(&clsc);
485 clsc.createEvents();
486 }
487 };
488
489 TRACE_REQUEST_FUNC(ClassLoaderStatistics) {
490 JfrClassLoaderStatsVMOperation op;
491 VMThread::execute(&op);
492 }
493
494 TRACE_REQUEST_FUNC(CompilerStatistics) {
495 EventCompilerStatistics event;
496 event.set_compileCount(CompileBroker::get_total_compile_count());
497 event.set_bailoutCount(CompileBroker::get_total_bailout_count());
498 event.set_invalidatedCount(CompileBroker::get_total_invalidated_count());
499 event.set_osrCompileCount(CompileBroker::get_total_osr_compile_count());
500 event.set_standardCompileCount(CompileBroker::get_total_standard_compile_count());
501 event.set_osrBytesCompiled(CompileBroker::get_sum_osr_bytes_compiled());
502 event.set_standardBytesCompiled(CompileBroker::get_sum_standard_bytes_compiled());
503 event.set_nmetodsSize(CompileBroker::get_sum_nmethod_size());
504 event.set_nmetodCodeSize(CompileBroker::get_sum_nmethod_code_size());
505 event.set_peakTimeSpent(CompileBroker::get_peak_compilation_time());
506 event.set_totalTimeSpent(CompileBroker::get_total_compilation_time());
507 event.commit();
508 }
509
510 TRACE_REQUEST_FUNC(CompilerConfiguration) {
511 EventCompilerConfiguration event;
512 event.set_threadCount(CICompilerCount);
513 event.set_tieredCompilation(TieredCompilation);
514 event.commit();
515 }
516
517 TRACE_REQUEST_FUNC(CodeCacheStatistics) {
518 EventCodeCacheStatistics event;
519 event.set_codeBlobType((u1)0/*bt*/); // XXX
520 event.set_startAddress((u8)CodeCache::low_bound());
521 event.set_reservedTopAddress((u8)CodeCache::high_bound());
522 event.set_entryCount(CodeCache::nof_blobs());
523 event.set_methodCount(CodeCache::nof_nmethods());
524 event.set_adaptorCount(CodeCache::nof_adapters());
525 event.set_unallocatedCapacity(CodeCache::unallocated_capacity());
526 event.set_fullCount(CodeCache::get_codemem_full_count());
527 event.commit();
528 }
529
530 TRACE_REQUEST_FUNC(CodeCacheConfiguration) {
531 EventCodeCacheConfiguration event;
532 event.set_initialSize(InitialCodeCacheSize);
533 event.set_reservedSize(ReservedCodeCacheSize);
534 event.set_nonNMethodSize(0/*NonNMethodCodeHeapSize*/); // XXX
535 event.set_profiledSize(0/*ProfiledCodeHeapSize*/); // XXX
536 event.set_nonProfiledSize(0/*NonProfiledCodeHeapSize*/); // XXX
537 event.set_expansionSize(CodeCacheExpansionSize);
538 event.set_minBlockLength(CodeCacheMinBlockLength);
539 event.set_startAddress((u8)CodeCache::low_bound());
540 event.set_reservedTopAddress((u8)CodeCache::high_bound());
541 event.commit();
542 }
543
544 TRACE_REQUEST_FUNC(CodeSweeperStatistics) {
545 EventCodeSweeperStatistics event;
546 event.set_sweepCount(NMethodSweeper::traversal_count());
547 event.set_methodReclaimedCount(NMethodSweeper::total_nof_methods_reclaimed());
548 event.set_totalSweepTime(NMethodSweeper::total_time_sweeping());
549 event.set_peakFractionTime(NMethodSweeper::peak_sweep_fraction_time());
550 event.set_peakSweepTime(NMethodSweeper::peak_sweep_time());
551 event.commit();
552 }
553
554 TRACE_REQUEST_FUNC(CodeSweeperConfiguration) {
555 EventCodeSweeperConfiguration event;
556 event.set_sweeperEnabled(MethodFlushing);
557 event.set_flushingEnabled(UseCodeCacheFlushing);
558 event.commit();
559 }

mercurial