src/hotspot/share/services/classLoadingService.cpp
changeset 47216 71c04702a3d5
parent 46766 1f26ac73b909
child 49824 e242740a92b8
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2003, 2017, 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 "classfile/systemDictionary.hpp"
       
    27 #include "memory/allocation.hpp"
       
    28 #include "memory/resourceArea.hpp"
       
    29 #include "memory/universe.hpp"
       
    30 #include "oops/oop.inline.hpp"
       
    31 #include "runtime/mutexLocker.hpp"
       
    32 #include "services/classLoadingService.hpp"
       
    33 #include "services/memoryService.hpp"
       
    34 #include "utilities/dtrace.hpp"
       
    35 #include "utilities/macros.hpp"
       
    36 #include "utilities/defaultStream.hpp"
       
    37 #include "logging/log.hpp"
       
    38 #include "logging/logConfiguration.hpp"
       
    39 
       
    40 #ifdef DTRACE_ENABLED
       
    41 
       
    42 // Only bother with this argument setup if dtrace is available
       
    43 
       
    44 #define HOTSPOT_CLASS_unloaded HOTSPOT_CLASS_UNLOADED
       
    45 #define HOTSPOT_CLASS_loaded HOTSPOT_CLASS_LOADED
       
    46 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared)  \
       
    47   {                                                 \
       
    48     char* data = NULL;                              \
       
    49     int len = 0;                                    \
       
    50     Symbol* name = (clss)->name();                  \
       
    51     if (name != NULL) {                             \
       
    52       data = (char*)name->bytes();                  \
       
    53       len = name->utf8_length();                    \
       
    54     }                                               \
       
    55     HOTSPOT_CLASS_##type( /* type = unloaded, loaded */ \
       
    56       data, len, (void*)(clss)->class_loader(), (shared)); \
       
    57   }
       
    58 
       
    59 #else //  ndef DTRACE_ENABLED
       
    60 
       
    61 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared)
       
    62 
       
    63 #endif
       
    64 
       
    65 #if INCLUDE_MANAGEMENT
       
    66 // counters for classes loaded from class files
       
    67 PerfCounter*    ClassLoadingService::_classes_loaded_count = NULL;
       
    68 PerfCounter*    ClassLoadingService::_classes_unloaded_count = NULL;
       
    69 PerfCounter*    ClassLoadingService::_classbytes_loaded = NULL;
       
    70 PerfCounter*    ClassLoadingService::_classbytes_unloaded = NULL;
       
    71 
       
    72 // counters for classes loaded from shared archive
       
    73 PerfCounter*    ClassLoadingService::_shared_classes_loaded_count = NULL;
       
    74 PerfCounter*    ClassLoadingService::_shared_classes_unloaded_count = NULL;
       
    75 PerfCounter*    ClassLoadingService::_shared_classbytes_loaded = NULL;
       
    76 PerfCounter*    ClassLoadingService::_shared_classbytes_unloaded = NULL;
       
    77 PerfVariable*   ClassLoadingService::_class_methods_size = NULL;
       
    78 
       
    79 void ClassLoadingService::init() {
       
    80   EXCEPTION_MARK;
       
    81 
       
    82   // These counters are for java.lang.management API support.
       
    83   // They are created even if -XX:-UsePerfData is set and in
       
    84   // that case, they will be allocated on C heap.
       
    85   _classes_loaded_count =
       
    86                  PerfDataManager::create_counter(JAVA_CLS, "loadedClasses",
       
    87                                                  PerfData::U_Events, CHECK);
       
    88 
       
    89   _classes_unloaded_count =
       
    90                  PerfDataManager::create_counter(JAVA_CLS, "unloadedClasses",
       
    91                                                  PerfData::U_Events, CHECK);
       
    92 
       
    93   _shared_classes_loaded_count =
       
    94                  PerfDataManager::create_counter(JAVA_CLS, "sharedLoadedClasses",
       
    95                                                  PerfData::U_Events, CHECK);
       
    96 
       
    97   _shared_classes_unloaded_count =
       
    98                  PerfDataManager::create_counter(JAVA_CLS, "sharedUnloadedClasses",
       
    99                                                  PerfData::U_Events, CHECK);
       
   100 
       
   101   if (UsePerfData) {
       
   102     _classbytes_loaded =
       
   103                  PerfDataManager::create_counter(SUN_CLS, "loadedBytes",
       
   104                                                  PerfData::U_Bytes, CHECK);
       
   105 
       
   106     _classbytes_unloaded =
       
   107                  PerfDataManager::create_counter(SUN_CLS, "unloadedBytes",
       
   108                                                  PerfData::U_Bytes, CHECK);
       
   109     _shared_classbytes_loaded =
       
   110                  PerfDataManager::create_counter(SUN_CLS, "sharedLoadedBytes",
       
   111                                                  PerfData::U_Bytes, CHECK);
       
   112 
       
   113     _shared_classbytes_unloaded =
       
   114                  PerfDataManager::create_counter(SUN_CLS, "sharedUnloadedBytes",
       
   115                                                  PerfData::U_Bytes, CHECK);
       
   116     _class_methods_size =
       
   117                  PerfDataManager::create_variable(SUN_CLS, "methodBytes",
       
   118                                                   PerfData::U_Bytes, CHECK);
       
   119   }
       
   120 }
       
   121 
       
   122 void ClassLoadingService::notify_class_unloaded(InstanceKlass* k) {
       
   123   DTRACE_CLASSLOAD_PROBE(unloaded, k, false);
       
   124   // Classes that can be unloaded must be non-shared
       
   125   _classes_unloaded_count->inc();
       
   126 
       
   127   if (UsePerfData) {
       
   128     // add the class size
       
   129     size_t size = compute_class_size(k);
       
   130     _classbytes_unloaded->inc(size);
       
   131 
       
   132     // Compute method size & subtract from running total.
       
   133     // We are called during phase 1 of mark sweep, so it's
       
   134     // still ok to iterate through Method*s here.
       
   135     Array<Method*>* methods = k->methods();
       
   136     for (int i = 0; i < methods->length(); i++) {
       
   137       _class_methods_size->inc(-methods->at(i)->size());
       
   138     }
       
   139   }
       
   140 
       
   141   if (log_is_enabled(Info, class, unload)) {
       
   142     ResourceMark rm;
       
   143     log_info(class, unload)("unloading class %s " INTPTR_FORMAT , k->external_name(), p2i(k));
       
   144   }
       
   145 }
       
   146 
       
   147 void ClassLoadingService::notify_class_loaded(InstanceKlass* k, bool shared_class) {
       
   148   DTRACE_CLASSLOAD_PROBE(loaded, k, shared_class);
       
   149   PerfCounter* classes_counter = (shared_class ? _shared_classes_loaded_count
       
   150                                                : _classes_loaded_count);
       
   151   // increment the count
       
   152   classes_counter->inc();
       
   153 
       
   154   if (UsePerfData) {
       
   155     PerfCounter* classbytes_counter = (shared_class ? _shared_classbytes_loaded
       
   156                                                     : _classbytes_loaded);
       
   157     // add the class size
       
   158     size_t size = compute_class_size(k);
       
   159     classbytes_counter->inc(size);
       
   160   }
       
   161 }
       
   162 
       
   163 size_t ClassLoadingService::compute_class_size(InstanceKlass* k) {
       
   164   // lifted from ClassStatistics.do_class(Klass* k)
       
   165 
       
   166   size_t class_size = 0;
       
   167 
       
   168   class_size += k->size();
       
   169 
       
   170   if (k->is_instance_klass()) {
       
   171     class_size += k->methods()->size();
       
   172     // FIXME: Need to count the contents of methods
       
   173     class_size += k->constants()->size();
       
   174     class_size += k->local_interfaces()->size();
       
   175     class_size += k->transitive_interfaces()->size();
       
   176     // We do not have to count implementors, since we only store one!
       
   177     // FIXME: How should these be accounted for, now when they have moved.
       
   178     //class_size += k->fields()->size();
       
   179   }
       
   180   return class_size * oopSize;
       
   181 }
       
   182 
       
   183 bool ClassLoadingService::set_verbose(bool verbose) {
       
   184   MutexLocker m(Management_lock);
       
   185   // verbose will be set to the previous value
       
   186   LogLevelType level = verbose ? LogLevel::Info : LogLevel::Off;
       
   187   LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, load));
       
   188   reset_trace_class_unloading();
       
   189   return verbose;
       
   190 }
       
   191 
       
   192 // Caller to this function must own Management_lock
       
   193 void ClassLoadingService::reset_trace_class_unloading() {
       
   194   assert(Management_lock->owned_by_self(), "Must own the Management_lock");
       
   195   bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
       
   196   LogLevelType level = value ? LogLevel::Info : LogLevel::Off;
       
   197   LogConfiguration::configure_stdout(level, false, LOG_TAGS(class, unload));
       
   198 }
       
   199 
       
   200 #endif // INCLUDE_MANAGEMENT