src/hotspot/share/memory/metaspace/metaspaceReport.cpp
branchstuefe-new-metaspace-branch
changeset 58063 bdf136b8ae0e
child 59134 b67820888eb3
equal deleted inserted replaced
58062:65cad575ace3 58063:bdf136b8ae0e
       
     1 /*
       
     2  * Copyright (c) 2018, 2019 SAP and/or its affiliates.
       
     3  * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
       
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     5  *
       
     6  * This code is free software; you can redistribute it and/or modify it
       
     7  * under the terms of the GNU General Public License version 2 only, as
       
     8  * published by the Free Software Foundation.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  *
       
    24  */
       
    25 #include "precompiled.hpp"
       
    26 #include "classfile/classLoaderData.hpp"
       
    27 #include "classfile/classLoaderDataGraph.hpp"
       
    28 #include "memory/metaspace/chunkHeaderPool.hpp"
       
    29 #include "memory/metaspace/chunkManager.hpp"
       
    30 #include "memory/metaspace/internStat.hpp"
       
    31 #include "memory/metaspace/metaspaceCommon.hpp"
       
    32 #include "memory/metaspace/metaspaceEnums.hpp"
       
    33 #include "memory/metaspace/metaspaceReport.hpp"
       
    34 #include "memory/metaspace/metaspaceStatistics.hpp"
       
    35 #include "memory/metaspace/printCLDMetaspaceInfoClosure.hpp"
       
    36 #include "memory/metaspace/runningCounters.hpp"
       
    37 #include "memory/metaspace/virtualSpaceList.hpp"
       
    38 #include "memory/metaspace.hpp"
       
    39 #include "runtime/os.hpp"
       
    40 
       
    41 namespace metaspace {
       
    42 
       
    43 static void print_vs(outputStream* out, size_t scale) {
       
    44 
       
    45   const size_t reserved_nc = RunningCounters::reserved_words_nonclass();
       
    46   const size_t committed_nc = RunningCounters::committed_words_nonclass();
       
    47   const int num_nodes_nc = VirtualSpaceList::vslist_nonclass()->num_nodes();
       
    48   const size_t reserved_c = RunningCounters::reserved_words_class();
       
    49   const size_t committed_c = RunningCounters::committed_words_class();
       
    50   const int num_nodes_c = VirtualSpaceList::vslist_class()->num_nodes();
       
    51 
       
    52   if (Metaspace::using_class_space()) {
       
    53 
       
    54     out->print("  Non-class space:  ");
       
    55     print_scaled_words(out, reserved_nc, scale, 7);
       
    56     out->print(" reserved, ");
       
    57     print_scaled_words_and_percentage(out, committed_nc, reserved_nc, scale, 7);
       
    58     out->print(" committed, ");
       
    59     out->print(" %d nodes.", num_nodes_nc);
       
    60     out->cr();
       
    61     out->print("      Class space:  ");
       
    62     print_scaled_words(out, reserved_c, scale, 7);
       
    63     out->print(" reserved, ");
       
    64     print_scaled_words_and_percentage(out, committed_c, reserved_c, scale, 7);
       
    65     out->print(" committed, ");
       
    66     out->print(" %d nodes.", num_nodes_c);
       
    67     out->cr();
       
    68     out->print("              Both:  ");
       
    69     print_scaled_words(out, reserved_c + reserved_nc, scale, 7);
       
    70     out->print(" reserved, ");
       
    71     print_scaled_words_and_percentage(out, committed_c + committed_nc, reserved_c + reserved_nc, scale, 7);
       
    72     out->print(" committed. ");
       
    73     out->cr();
       
    74 
       
    75   } else {
       
    76     assert(committed_c == 0 && reserved_c == 0 && num_nodes_c == 0, "Sanity");
       
    77     print_scaled_words(out, reserved_nc, scale, 7);
       
    78     out->print(" reserved, ");
       
    79     print_scaled_words_and_percentage(out, committed_nc, reserved_nc, scale, 7);
       
    80     out->print(" committed, ");
       
    81     out->print(" %d nodes.", num_nodes_nc);
       
    82     out->cr();
       
    83   }
       
    84 }
       
    85 
       
    86 static void print_settings(outputStream* out, size_t scale) {
       
    87   out->print("MaxMetaspaceSize: ");
       
    88   if (MaxMetaspaceSize >= (max_uintx) - (2 * os::vm_page_size())) {
       
    89     // aka "very big". Default is max_uintx, but due to rounding in arg parsing the real
       
    90     // value is smaller.
       
    91     out->print("unlimited");
       
    92   } else {
       
    93     print_human_readable_size(out, MaxMetaspaceSize, scale);
       
    94   }
       
    95   out->cr();
       
    96   if (Metaspace::using_class_space()) {
       
    97     out->print("CompressedClassSpaceSize: ");
       
    98     print_human_readable_size(out, CompressedClassSpaceSize, scale);
       
    99   }
       
   100   out->cr();
       
   101   out->print("InitialBootClassLoaderMetaspaceSize: ");
       
   102   print_human_readable_size(out, InitialBootClassLoaderMetaspaceSize, scale);
       
   103   out->cr();
       
   104   Settings::print_on(out);
       
   105 }
       
   106 
       
   107 // This will print out a basic metaspace usage report but
       
   108 // unlike print_report() is guaranteed not to lock or to walk the CLDG.
       
   109 void MetaspaceReporter::print_basic_report(outputStream* out, size_t scale) {
       
   110 
       
   111   if (!Metaspace::initialized()) {
       
   112     out->print_cr("Metaspace not yet initialized.");
       
   113     return;
       
   114   }
       
   115 
       
   116   out->cr();
       
   117   out->print_cr("Usage:");
       
   118 
       
   119   if (Metaspace::using_class_space()) {
       
   120     out->print("  Non-class:  ");
       
   121   }
       
   122 
       
   123   // Note: since we want to purely rely on counters, without any locking or walking the CLDG,
       
   124   // for Usage stats (statistics over in-use chunks) all we can print is the
       
   125   // used words. We cannot print committed areas, or free/waste areas, of in-use chunks require
       
   126   // walking.
       
   127   const size_t used_nc = MetaspaceUtils::used_words(metaspace::NonClassType);
       
   128 
       
   129   print_scaled_words(out, used_nc, scale, 5);
       
   130   out->print(" used.");
       
   131   out->cr();
       
   132 
       
   133   if (Metaspace::using_class_space()) {
       
   134     const size_t used_c = MetaspaceUtils::used_words(metaspace::ClassType);
       
   135     out->print("      Class:  ");
       
   136     print_scaled_words(out, used_c, scale, 5);
       
   137     out->print(" used.");
       
   138     out->cr();
       
   139 
       
   140     out->print("       Both:  ");
       
   141     const size_t used = used_nc + used_c;
       
   142     print_scaled_words(out, used, scale, 5);
       
   143     out->print(" used.");
       
   144     out->cr();
       
   145   }
       
   146 
       
   147   out->cr();
       
   148   out->print_cr("Virtual space:");
       
   149 
       
   150   print_vs(out, scale);
       
   151 
       
   152   out->cr();
       
   153   out->print_cr("Chunk freelists:");
       
   154 
       
   155   if (Metaspace::using_class_space()) {
       
   156     out->print("   Non-Class:  ");
       
   157   }
       
   158   print_scaled_words(out, ChunkManager::chunkmanager_nonclass()->total_word_size(), scale);
       
   159   out->cr();
       
   160   if (Metaspace::using_class_space()) {
       
   161     out->print("       Class:  ");
       
   162     print_scaled_words(out, ChunkManager::chunkmanager_class()->total_word_size(), scale);
       
   163     out->cr();
       
   164     out->print("        Both:  ");
       
   165     print_scaled_words(out, ChunkManager::chunkmanager_nonclass()->total_word_size() +
       
   166                             ChunkManager::chunkmanager_class()->total_word_size(), scale);
       
   167     out->cr();
       
   168   }
       
   169 
       
   170   out->cr();
       
   171 
       
   172   // Print basic settings
       
   173   print_settings(out, scale);
       
   174 
       
   175   out->cr();
       
   176 
       
   177 #ifdef ASSERT
       
   178   out->cr();
       
   179   out->print_cr("Internal statistics:");
       
   180   out->cr();
       
   181   InternalStats::print_on(out);
       
   182   out->cr();
       
   183 #endif
       
   184 }
       
   185 
       
   186 void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags) {
       
   187 
       
   188   if (!Metaspace::initialized()) {
       
   189     out->print_cr("Metaspace not yet initialized.");
       
   190     return;
       
   191   }
       
   192 
       
   193   const bool print_loaders = (flags & rf_show_loaders) > 0;
       
   194   const bool print_classes = (flags & rf_show_classes) > 0;
       
   195   const bool print_by_chunktype = (flags & rf_break_down_by_chunktype) > 0;
       
   196   const bool print_by_spacetype = (flags & rf_break_down_by_spacetype) > 0;
       
   197 
       
   198   // Some report options require walking the class loader data graph.
       
   199   metaspace::PrintCLDMetaspaceInfoClosure cl(out, scale, print_loaders, print_classes, print_by_chunktype);
       
   200   if (print_loaders) {
       
   201     out->cr();
       
   202     out->print_cr("Usage per loader:");
       
   203     out->cr();
       
   204   }
       
   205 
       
   206   ClassLoaderDataGraph::loaded_cld_do(&cl); // collect data and optionally print
       
   207 
       
   208   // Print totals, broken up by space type.
       
   209   if (print_by_spacetype) {
       
   210     out->cr();
       
   211     out->print_cr("Usage per space type:");
       
   212     out->cr();
       
   213     for (int space_type = (int)metaspace::ZeroMetaspaceType;
       
   214          space_type < (int)metaspace::MetaspaceTypeCount; space_type ++)
       
   215     {
       
   216       uintx num_loaders = cl._num_loaders_by_spacetype[space_type];
       
   217       uintx num_classes = cl._num_classes_by_spacetype[space_type];
       
   218       out->print("%s - " UINTX_FORMAT " %s",
       
   219         describe_spacetype((MetaspaceType)space_type),
       
   220         num_loaders, loaders_plural(num_loaders));
       
   221       if (num_classes > 0) {
       
   222         out->print(", ");
       
   223 
       
   224         print_number_of_classes(out, num_classes, cl._num_classes_shared_by_spacetype[space_type]);
       
   225         out->print(":");
       
   226         cl._stats_by_spacetype[space_type].print_on(out, scale, print_by_chunktype);
       
   227       } else {
       
   228         out->print(".");
       
   229         out->cr();
       
   230       }
       
   231       out->cr();
       
   232     }
       
   233   }
       
   234 
       
   235   // Print totals for in-use data:
       
   236   out->cr();
       
   237   {
       
   238     uintx num_loaders = cl._num_loaders;
       
   239     out->print("Total Usage - " UINTX_FORMAT " %s, ",
       
   240       num_loaders, loaders_plural(num_loaders));
       
   241     print_number_of_classes(out, cl._num_classes, cl._num_classes_shared);
       
   242     out->print(":");
       
   243     cl._stats_total.print_on(out, scale, print_by_chunktype);
       
   244     out->cr();
       
   245   }
       
   246 
       
   247   /////////////////////////////////////////////////
       
   248   // -- Print Virtual space.
       
   249   out->cr();
       
   250   out->print_cr("Virtual space:");
       
   251 
       
   252   print_vs(out, scale);
       
   253 
       
   254   // -- Print VirtualSpaceList details.
       
   255   if ((flags & rf_show_vslist) > 0) {
       
   256     out->cr();
       
   257     out->print_cr("Virtual space list%s:", Metaspace::using_class_space() ? "s" : "");
       
   258 
       
   259     if (Metaspace::using_class_space()) {
       
   260       out->print_cr("   Non-Class:");
       
   261     }
       
   262     VirtualSpaceList::vslist_nonclass()->print_on(out);
       
   263     out->cr();
       
   264     if (Metaspace::using_class_space()) {
       
   265       out->print_cr("       Class:");
       
   266       VirtualSpaceList::vslist_class()->print_on(out);
       
   267       out->cr();
       
   268     }
       
   269   }
       
   270   out->cr();
       
   271 
       
   272   // -- Print VirtualSpaceList map.
       
   273 /* Deactivated for now.
       
   274   if ((flags & rf_show_vsmap) > 0) {
       
   275     out->cr();
       
   276     out->print_cr("Virtual space map:");
       
   277 
       
   278     if (Metaspace::using_class_space()) {
       
   279       out->print_cr("   Non-Class:");
       
   280     }
       
   281     Metaspace::space_list()->print_map(out);
       
   282     if (Metaspace::using_class_space()) {
       
   283       out->print_cr("       Class:");
       
   284       Metaspace::class_space_list()->print_map(out);
       
   285     }
       
   286   }
       
   287   out->cr();
       
   288 */
       
   289 
       
   290   //////////// Freelists (ChunkManager) section ///////////////////////////
       
   291 
       
   292   out->cr();
       
   293   out->print_cr("Chunk freelist%s:", Metaspace::using_class_space() ? "s" : "");
       
   294 
       
   295   cm_stats_t non_class_cm_stat;
       
   296   cm_stats_t class_cm_stat;
       
   297   cm_stats_t total_cm_stat;
       
   298 
       
   299   ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
       
   300   if (Metaspace::using_class_space()) {
       
   301     ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
       
   302     ChunkManager::chunkmanager_class()->add_to_statistics(&class_cm_stat);
       
   303     total_cm_stat.add(non_class_cm_stat);
       
   304     total_cm_stat.add(class_cm_stat);
       
   305 
       
   306     out->print_cr("   Non-Class:");
       
   307     non_class_cm_stat.print_on(out, scale);
       
   308     out->cr();
       
   309     out->print_cr("       Class:");
       
   310     class_cm_stat.print_on(out, scale);
       
   311     out->cr();
       
   312     out->print_cr("        Both:");
       
   313     total_cm_stat.print_on(out, scale);
       
   314     out->cr();
       
   315   } else {
       
   316     ChunkManager::chunkmanager_nonclass()->add_to_statistics(&non_class_cm_stat);
       
   317     non_class_cm_stat.print_on(out, scale);
       
   318     out->cr();
       
   319   }
       
   320 
       
   321   //////////// Waste section ///////////////////////////
       
   322   // As a convenience, print a summary of common waste.
       
   323   out->cr();
       
   324   out->print("Waste (unused committed space):");
       
   325   // For all wastages, print percentages from total. As total use the total size of memory committed for metaspace.
       
   326   const size_t committed_words = RunningCounters::committed_words();
       
   327 
       
   328   out->print("(percentages refer to total committed size ");
       
   329   print_scaled_words(out, committed_words, scale);
       
   330   out->print_cr("):");
       
   331 
       
   332   // Print waste for in-use chunks.
       
   333   in_use_chunk_stats_t ucs_nonclass = cl._stats_total.sm_stats_nonclass.totals();
       
   334   in_use_chunk_stats_t ucs_class = cl._stats_total.sm_stats_class.totals();
       
   335   const size_t waste_in_chunks_in_use = ucs_nonclass.waste_words + ucs_class.waste_words;
       
   336   const size_t free_in_chunks_in_use = ucs_nonclass.free_words + ucs_class.free_words;
       
   337 
       
   338   out->print("        Waste in chunks in use: ");
       
   339   print_scaled_words_and_percentage(out, waste_in_chunks_in_use, committed_words, scale, 6);
       
   340   out->cr();
       
   341   out->print("        Free in chunks in use: ");
       
   342   print_scaled_words_and_percentage(out, free_in_chunks_in_use, committed_words, scale, 6);
       
   343   out->cr();
       
   344 
       
   345   // Print waste in free chunks.
       
   346   const size_t committed_in_free_chunks = total_cm_stat.total_committed_word_size();
       
   347   out->print("                In free chunks: ");
       
   348   print_scaled_words_and_percentage(out, committed_in_free_chunks, committed_words, scale, 6);
       
   349   out->cr();
       
   350 
       
   351   // Print waste in deallocated blocks.
       
   352   const uintx free_blocks_num =
       
   353       cl._stats_total.sm_stats_nonclass.free_blocks_num +
       
   354       cl._stats_total.sm_stats_class.free_blocks_num;
       
   355   const size_t free_blocks_cap_words =
       
   356       cl._stats_total.sm_stats_nonclass.free_blocks_word_size +
       
   357       cl._stats_total.sm_stats_class.free_blocks_word_size;
       
   358   out->print("Deallocated from chunks in use: ");
       
   359   print_scaled_words_and_percentage(out, free_blocks_cap_words, committed_words, scale, 6);
       
   360   out->print(" (" UINTX_FORMAT " blocks)", free_blocks_num);
       
   361   out->cr();
       
   362 
       
   363   // Print total waste.
       
   364   const size_t total_waste =
       
   365       waste_in_chunks_in_use +
       
   366       free_in_chunks_in_use +
       
   367       committed_in_free_chunks +
       
   368       free_blocks_cap_words;
       
   369   out->print("                       -total-: ");
       
   370   print_scaled_words_and_percentage(out, total_waste, committed_words, scale, 6);
       
   371   out->cr();
       
   372 
       
   373   // Also print chunk header pool size.
       
   374   out->cr();
       
   375   out->print("chunk header pool: %u items, ", ChunkHeaderPool::pool().used());
       
   376   print_scaled_words(out, ChunkHeaderPool::pool().memory_footprint_words(), scale);
       
   377   out->print(".");
       
   378   out->cr();
       
   379 
       
   380   // Print internal statistics
       
   381 #ifdef ASSERT
       
   382   out->cr();
       
   383   out->print_cr("Internal statistics:");
       
   384   out->cr();
       
   385   InternalStats::print_on(out);
       
   386   out->cr();
       
   387 #endif
       
   388 
       
   389   // Print some interesting settings
       
   390   out->cr();
       
   391   out->print_cr("Settings:");
       
   392   print_settings(out, scale);
       
   393 
       
   394   out->cr();
       
   395   out->cr();
       
   396 
       
   397 } // MetaspaceUtils::print_report()
       
   398 
       
   399 } // namespace metaspace
       
   400