src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp
changeset 55571 49102ba8cf14
parent 52925 9c18c9d839d3
child 58823 6a21dba79b81
equal deleted inserted replaced
55570:1e95931e7d8f 55571:49102ba8cf14
     1 /*
     1 /*
     2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "jfr/leakprofiler/emitEventOperation.hpp"
       
    27 #include "jfr/leakprofiler/leakProfiler.hpp"
    26 #include "jfr/leakprofiler/leakProfiler.hpp"
    28 #include "jfr/leakprofiler/startOperation.hpp"
    27 #include "jfr/leakprofiler/startOperation.hpp"
    29 #include "jfr/leakprofiler/stopOperation.hpp"
    28 #include "jfr/leakprofiler/stopOperation.hpp"
       
    29 #include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
    30 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    30 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
    31 #include "jfr/recorder/service/jfrOptionSet.hpp"
    31 #include "jfr/recorder/service/jfrOptionSet.hpp"
       
    32 #include "logging/log.hpp"
    32 #include "memory/iterator.hpp"
    33 #include "memory/iterator.hpp"
    33 #include "oops/oop.hpp"
       
    34 #include "runtime/atomic.hpp"
       
    35 #include "runtime/orderAccess.hpp"
       
    36 #include "runtime/thread.inline.hpp"
    34 #include "runtime/thread.inline.hpp"
    37 #include "runtime/vmThread.hpp"
    35 #include "runtime/vmThread.hpp"
    38 #include "utilities/ostream.hpp"
       
    39 
    36 
    40 // Only to be updated during safepoint
    37 bool LeakProfiler::is_running() {
    41 ObjectSampler* LeakProfiler::_object_sampler = NULL;
    38   return ObjectSampler::is_created();
       
    39 }
    42 
    40 
    43 static volatile jbyte suspended = 0;
    41 bool LeakProfiler::start(int sample_count) {
    44 bool LeakProfiler::start(jint sample_count) {
    42   if (is_running()) {
       
    43     return true;
       
    44   }
       
    45 
       
    46   // Allows user to disable leak profiler on command line by setting queue size to zero.
       
    47   if (sample_count == 0) {
       
    48     return false;
       
    49   }
       
    50 
    45   if (UseZGC) {
    51   if (UseZGC) {
    46     log_warning(jfr)("LeakProfiler is currently not supported in combination with ZGC");
    52     log_warning(jfr)("LeakProfiler is currently not supported in combination with ZGC");
    47     return false;
    53     return false;
    48   }
    54   }
    49 
    55 
    50   if (UseShenandoahGC) {
    56   if (UseShenandoahGC) {
    51     log_warning(jfr)("LeakProfiler is currently not supported in combination with Shenandoah GC");
    57     log_warning(jfr)("LeakProfiler is currently not supported in combination with Shenandoah GC");
    52     return false;
    58     return false;
    53   }
    59   }
    54 
    60 
    55   if (_object_sampler != NULL) {
    61   assert(!is_running(), "invariant");
    56     // already started
    62   assert(sample_count > 0, "invariant");
    57     return true;
    63 
       
    64   // schedule the safepoint operation for installing the object sampler
       
    65   StartOperation op(sample_count);
       
    66   VMThread::execute(&op);
       
    67 
       
    68   if (!is_running()) {
       
    69     log_trace(jfr, system)("Object sampling could not be started because the sampler could not be allocated");
       
    70     return false;
    58   }
    71   }
    59   // Allows user to disable leak profiler on command line by setting queue size to zero.
    72   assert(is_running(), "invariant");
    60   if (sample_count > 0) {
    73   log_trace(jfr, system)("Object sampling started");
    61     StartOperation op(sample_count);
    74   return true;
    62     VMThread::execute(&op);
       
    63     return _object_sampler != NULL;
       
    64   }
       
    65   return false;
       
    66 }
    75 }
    67 
    76 
    68 bool LeakProfiler::stop() {
    77 bool LeakProfiler::stop() {
    69   if (_object_sampler == NULL) {
    78   if (!is_running()) {
    70     // already stopped/not started
    79     return false;
    71     return true;
       
    72   }
    80   }
       
    81 
       
    82   // schedule the safepoint operation for uninstalling and destroying the object sampler
    73   StopOperation op;
    83   StopOperation op;
    74   VMThread::execute(&op);
    84   VMThread::execute(&op);
    75   return _object_sampler == NULL;
    85 
       
    86   assert(!is_running(), "invariant");
       
    87   log_trace(jfr, system)("Object sampling stopped");
       
    88   return true;
    76 }
    89 }
    77 
    90 
    78 void LeakProfiler::emit_events(jlong cutoff_ticks, bool emit_all) {
    91 void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all) {
    79   if (!is_running()) {
    92   if (!is_running()) {
    80     return;
    93     return;
    81   }
    94   }
    82   EmitEventOperation op(cutoff_ticks, emit_all);
    95   // exclusive access to object sampler instance
    83   VMThread::execute(&op);
    96   ObjectSampler* const sampler = ObjectSampler::acquire();
       
    97   assert(sampler != NULL, "invariant");
       
    98   EventEmitter::emit(sampler, cutoff_ticks, emit_all);
       
    99   ObjectSampler::release();
    84 }
   100 }
    85 
   101 
    86 void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
   102 void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
    87   assert(SafepointSynchronize::is_at_safepoint(),
   103   assert(SafepointSynchronize::is_at_safepoint(),
    88     "Leak Profiler::oops_do(...) may only be called during safepoint");
   104     "Leak Profiler::oops_do(...) may only be called during safepoint");
    89 
   105   if (is_running()) {
    90   if (_object_sampler != NULL) {
   106     ObjectSampler::oops_do(is_alive, f);
    91     _object_sampler->oops_do(is_alive, f);
       
    92   }
   107   }
    93 }
   108 }
    94 
   109 
    95 void LeakProfiler::sample(HeapWord* object,
   110 void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) {
    96                           size_t size,
       
    97                           JavaThread* thread) {
       
    98   assert(is_running(), "invariant");
   111   assert(is_running(), "invariant");
    99   assert(thread != NULL, "invariant");
   112   assert(thread != NULL, "invariant");
   100   assert(thread->thread_state() == _thread_in_vm, "invariant");
   113   assert(thread->thread_state() == _thread_in_vm, "invariant");
   101 
   114 
   102   // exclude compiler threads and code sweeper thread
   115   // exclude compiler threads and code sweeper thread
   103   if (thread->is_hidden_from_external_view()) {
   116   if (thread->is_hidden_from_external_view()) {
   104     return;
   117     return;
   105   }
   118   }
   106 
   119 
   107   _object_sampler->add(object, size, thread);
   120   ObjectSampler::sample(object, size, thread);
   108 }
   121 }
   109 
       
   110 ObjectSampler* LeakProfiler::object_sampler() {
       
   111   assert(is_suspended() || SafepointSynchronize::is_at_safepoint(),
       
   112     "Leak Profiler::object_sampler() may only be called during safepoint");
       
   113   return _object_sampler;
       
   114 }
       
   115 
       
   116 void LeakProfiler::set_object_sampler(ObjectSampler* object_sampler) {
       
   117   assert(SafepointSynchronize::is_at_safepoint(),
       
   118     "Leak Profiler::set_object_sampler() may only be called during safepoint");
       
   119   _object_sampler = object_sampler;
       
   120 }
       
   121 
       
   122 bool LeakProfiler::is_running() {
       
   123   return _object_sampler != NULL && !suspended;
       
   124 }
       
   125 
       
   126 bool LeakProfiler::is_suspended() {
       
   127   return _object_sampler != NULL && suspended;
       
   128 }
       
   129 
       
   130 void LeakProfiler::resume() {
       
   131   assert(is_suspended(), "invariant");
       
   132   OrderAccess::storestore();
       
   133   Atomic::store((jbyte)0, &suspended);
       
   134   assert(is_running(), "invariant");
       
   135 }
       
   136 
       
   137 void LeakProfiler::suspend() {
       
   138   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
       
   139   assert(_object_sampler != NULL, "invariant");
       
   140   assert(!is_suspended(), "invariant");
       
   141   suspended = (jbyte)1; // safepoint visible
       
   142 }