src/share/vm/services/memTrackWorker.cpp

changeset 7074
833b0f92429a
parent 7073
4d3a43351904
child 7075
ac12996df59b
     1.1 --- a/src/share/vm/services/memTrackWorker.cpp	Wed Aug 27 09:36:55 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,212 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.
    1.11 - *
    1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 - * version 2 for more details (a copy is included in the LICENSE file that
    1.16 - * accompanied this code).
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License version
    1.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 - *
    1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 - * or visit www.oracle.com if you need additional information or have any
    1.24 - * questions.
    1.25 - *
    1.26 - */
    1.27 -
    1.28 -#include "precompiled.hpp"
    1.29 -#include "runtime/threadCritical.hpp"
    1.30 -#include "services/memTracker.hpp"
    1.31 -#include "services/memTrackWorker.hpp"
    1.32 -#include "utilities/decoder.hpp"
    1.33 -#include "utilities/vmError.hpp"
    1.34 -
    1.35 -
    1.36 -void GenerationData::reset() {
    1.37 -  _number_of_classes = 0;
    1.38 -  while (_recorder_list != NULL) {
    1.39 -    MemRecorder* tmp = _recorder_list;
    1.40 -    _recorder_list = _recorder_list->next();
    1.41 -    MemTracker::release_thread_recorder(tmp);
    1.42 -  }
    1.43 -}
    1.44 -
    1.45 -MemTrackWorker::MemTrackWorker(MemSnapshot* snapshot): _snapshot(snapshot) {
    1.46 -  // create thread uses cgc thread type for now. We should revisit
    1.47 -  // the option, or create new thread type.
    1.48 -  _has_error = !os::create_thread(this, os::cgc_thread);
    1.49 -  set_name("MemTrackWorker");
    1.50 -
    1.51 -  // initial generation circuit buffer
    1.52 -  if (!has_error()) {
    1.53 -    _head = _tail = 0;
    1.54 -    for(int index = 0; index < MAX_GENERATIONS; index ++) {
    1.55 -      ::new ((void*)&_gen[index]) GenerationData();
    1.56 -    }
    1.57 -  }
    1.58 -  NOT_PRODUCT(_sync_point_count = 0;)
    1.59 -  NOT_PRODUCT(_merge_count = 0;)
    1.60 -  NOT_PRODUCT(_last_gen_in_use = 0;)
    1.61 -}
    1.62 -
    1.63 -MemTrackWorker::~MemTrackWorker() {
    1.64 -  for (int index = 0; index < MAX_GENERATIONS; index ++) {
    1.65 -    _gen[index].reset();
    1.66 -  }
    1.67 -}
    1.68 -
    1.69 -void* MemTrackWorker::operator new(size_t size) throw() {
    1.70 -  assert(false, "use nothrow version");
    1.71 -  return NULL;
    1.72 -}
    1.73 -
    1.74 -void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) throw() {
    1.75 -  return allocate(size, false, mtNMT);
    1.76 -}
    1.77 -
    1.78 -void MemTrackWorker::start() {
    1.79 -  os::start_thread(this);
    1.80 -}
    1.81 -
    1.82 -/*
    1.83 - * Native memory tracking worker thread loop:
    1.84 - *   1. merge one generation of memory recorders to staging area
    1.85 - *   2. promote staging data to memory snapshot
    1.86 - *
    1.87 - * This thread can run through safepoint.
    1.88 - */
    1.89 -
    1.90 -void MemTrackWorker::run() {
    1.91 -  assert(MemTracker::is_on(), "native memory tracking is off");
    1.92 -  this->initialize_thread_local_storage();
    1.93 -  this->record_stack_base_and_size();
    1.94 -  assert(_snapshot != NULL, "Worker should not be started");
    1.95 -  MemRecorder* rec;
    1.96 -  unsigned long processing_generation = 0;
    1.97 -  bool          worker_idle = false;
    1.98 -
    1.99 -  while (!MemTracker::shutdown_in_progress()) {
   1.100 -    NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
   1.101 -    {
   1.102 -      // take a recorder from earliest generation in buffer
   1.103 -      ThreadCritical tc;
   1.104 -      rec = _gen[_head].next_recorder();
   1.105 -    }
   1.106 -    if (rec != NULL) {
   1.107 -      if (rec->get_generation() != processing_generation || worker_idle) {
   1.108 -        processing_generation = rec->get_generation();
   1.109 -        worker_idle = false;
   1.110 -        MemTracker::set_current_processing_generation(processing_generation);
   1.111 -      }
   1.112 -
   1.113 -      // merge the recorder into staging area
   1.114 -      if (!_snapshot->merge(rec)) {
   1.115 -        MemTracker::shutdown(MemTracker::NMT_out_of_memory);
   1.116 -      } else {
   1.117 -        NOT_PRODUCT(_merge_count ++;)
   1.118 -      }
   1.119 -      MemTracker::release_thread_recorder(rec);
   1.120 -    } else {
   1.121 -      // no more recorder to merge, promote staging area
   1.122 -      // to snapshot
   1.123 -      if (_head != _tail) {
   1.124 -        long number_of_classes;
   1.125 -        {
   1.126 -          ThreadCritical tc;
   1.127 -          if (_gen[_head].has_more_recorder() || _head == _tail) {
   1.128 -            continue;
   1.129 -          }
   1.130 -          number_of_classes = _gen[_head].number_of_classes();
   1.131 -          _gen[_head].reset();
   1.132 -
   1.133 -          // done with this generation, increment _head pointer
   1.134 -          _head = (_head + 1) % MAX_GENERATIONS;
   1.135 -        }
   1.136 -        // promote this generation data to snapshot
   1.137 -        if (!_snapshot->promote(number_of_classes)) {
   1.138 -          // failed to promote, means out of memory
   1.139 -          MemTracker::shutdown(MemTracker::NMT_out_of_memory);
   1.140 -        }
   1.141 -      } else {
   1.142 -        // worker thread is idle
   1.143 -        worker_idle = true;
   1.144 -        MemTracker::report_worker_idle();
   1.145 -        _snapshot->wait(1000);
   1.146 -        ThreadCritical tc;
   1.147 -        // check if more data arrived
   1.148 -        if (!_gen[_head].has_more_recorder()) {
   1.149 -          _gen[_head].add_recorders(MemTracker::get_pending_recorders());
   1.150 -        }
   1.151 -      }
   1.152 -    }
   1.153 -  }
   1.154 -  assert(MemTracker::shutdown_in_progress(), "just check");
   1.155 -
   1.156 -  // transits to final shutdown
   1.157 -  MemTracker::final_shutdown();
   1.158 -}
   1.159 -
   1.160 -// at synchronization point, where 'safepoint visible' Java threads are blocked
   1.161 -// at a safepoint, and the rest of threads are blocked on ThreadCritical lock.
   1.162 -// The caller MemTracker::sync() already takes ThreadCritical before calling this
   1.163 -// method.
   1.164 -//
   1.165 -// Following tasks are performed:
   1.166 -//   1. add all recorders in pending queue to current generation
   1.167 -//   2. increase generation
   1.168 -
   1.169 -void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) {
   1.170 -  NOT_PRODUCT(_sync_point_count ++;)
   1.171 -  assert(count_recorder(rec) <= MemRecorder::_instance_count,
   1.172 -    "pending queue has infinite loop");
   1.173 -
   1.174 -  bool out_of_generation_buffer = false;
   1.175 -  // check shutdown state inside ThreadCritical
   1.176 -  if (MemTracker::shutdown_in_progress()) return;
   1.177 -
   1.178 -  _gen[_tail].set_number_of_classes(number_of_classes);
   1.179 -  // append the recorders to the end of the generation
   1.180 -  _gen[_tail].add_recorders(rec);
   1.181 -  assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count,
   1.182 -    "after add to current generation has infinite loop");
   1.183 -  // we have collected all recorders for this generation. If there is data,
   1.184 -  // we need to increment _tail to start a new generation.
   1.185 -  if (_gen[_tail].has_more_recorder()  || _head == _tail) {
   1.186 -    _tail = (_tail + 1) % MAX_GENERATIONS;
   1.187 -    out_of_generation_buffer = (_tail == _head);
   1.188 -  }
   1.189 -
   1.190 -  if (out_of_generation_buffer) {
   1.191 -    MemTracker::shutdown(MemTracker::NMT_out_of_generation);
   1.192 -  }
   1.193 -}
   1.194 -
   1.195 -#ifndef PRODUCT
   1.196 -int MemTrackWorker::count_recorder(const MemRecorder* head) {
   1.197 -  int count = 0;
   1.198 -  while(head != NULL) {
   1.199 -    count ++;
   1.200 -    head = head->next();
   1.201 -  }
   1.202 -  return count;
   1.203 -}
   1.204 -
   1.205 -int MemTrackWorker::count_pending_recorders() const {
   1.206 -  int count = 0;
   1.207 -  for (int index = 0; index < MAX_GENERATIONS; index ++) {
   1.208 -    MemRecorder* head = _gen[index].peek();
   1.209 -    if (head != NULL) {
   1.210 -      count += count_recorder(head);
   1.211 -    }
   1.212 -  }
   1.213 -  return count;
   1.214 -}
   1.215 -#endif

mercurial