leakProfiler.cpp 3.5 KB
Newer Older
A
apetushkov 已提交
1
/*
2
 * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
A
apetushkov 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/leakprofiler/startOperation.hpp"
#include "jfr/leakprofiler/stopOperation.hpp"
29
#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
A
apetushkov 已提交
30 31 32 33 34 35
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "memory/iterator.hpp"
#include "runtime/thread.inline.hpp"
#include "runtime/vmThread.hpp"

36 37 38
bool LeakProfiler::is_running() {
  return ObjectSampler::is_created();
}
A
apetushkov 已提交
39

40 41
bool LeakProfiler::start(int sample_count) {
  if (is_running()) {
A
apetushkov 已提交
42 43
    return true;
  }
44

A
apetushkov 已提交
45
  // Allows user to disable leak profiler on command line by setting queue size to zero.
46 47 48 49 50 51 52 53 54 55 56 57 58 59
  if (sample_count == 0) {
    return false;
  }

  assert(!is_running(), "invariant");
  assert(sample_count > 0, "invariant");

  // schedule the safepoint operation for installing the object sampler
  StartOperation op(sample_count);
  VMThread::execute(&op);

  if (!is_running()) {
    if (LogJFR && Verbose) tty->print_cr("Object sampling could not be started because the sampler could not be allocated");
    return false;
A
apetushkov 已提交
60
  }
61 62 63
  assert(is_running(), "invariant");
  if (LogJFR && Verbose) tty->print_cr("Object sampling started");
  return true;
A
apetushkov 已提交
64 65 66
}

bool LeakProfiler::stop() {
67 68
  if (!is_running()) {
    return false;
A
apetushkov 已提交
69
  }
70 71

  // schedule the safepoint operation for uninstalling and destroying the object sampler
A
apetushkov 已提交
72 73
  StopOperation op;
  VMThread::execute(&op);
74 75 76 77

  assert(!is_running(), "invariant");
  if (LogJFR && Verbose) tty->print_cr("Object sampling stopped");
  return true;
A
apetushkov 已提交
78 79
}

80
void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all) {
A
apetushkov 已提交
81 82 83
  if (!is_running()) {
    return;
  }
84 85 86 87 88
  // exclusive access to object sampler instance
  ObjectSampler* const sampler = ObjectSampler::acquire();
  assert(sampler != NULL, "invariant");
  EventEmitter::emit(sampler, cutoff_ticks, emit_all);
  ObjectSampler::release();
A
apetushkov 已提交
89 90 91 92 93
}

void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
  assert(SafepointSynchronize::is_at_safepoint(),
    "Leak Profiler::oops_do(...) may only be called during safepoint");
94 95
  if (is_running()) {
    ObjectSampler::oops_do(is_alive, f);
A
apetushkov 已提交
96 97 98
  }
}

99
void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) {
A
apetushkov 已提交
100 101 102 103 104 105 106 107 108
  assert(is_running(), "invariant");
  assert(thread != NULL, "invariant");
  assert(thread->thread_state() == _thread_in_vm, "invariant");

  // exclude compiler threads and code sweeper thread
  if (thread->is_hidden_from_external_view()) {
    return;
  }

109
  ObjectSampler::sample(object, size, thread);
A
apetushkov 已提交
110
}