2055 MutexLockerEx cl(SpaceManager::expand_lock(), |
2066 MutexLockerEx cl(SpaceManager::expand_lock(), |
2056 Mutex::_no_safepoint_check_flag); |
2067 Mutex::_no_safepoint_check_flag); |
2057 locked_get_statistics(stat); |
2068 locked_get_statistics(stat); |
2058 } |
2069 } |
2059 |
2070 |
2060 void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out) { |
2071 void ChunkManager::print_statistics(const ChunkManagerStatistics* stat, outputStream* out, size_t scale) { |
2061 size_t total = 0; |
2072 size_t total = 0; |
|
2073 assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale"); |
|
2074 |
|
2075 const char* unit = scale_unit(scale); |
2062 for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { |
2076 for (ChunkIndex i = ZeroIndex; i < NumberOfFreeLists; i = next_chunk_index(i)) { |
2063 out->print_cr(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total " SIZE_FORMAT " bytes", |
2077 out->print(" " SIZE_FORMAT " %s (" SIZE_FORMAT " bytes) chunks, total ", |
2064 stat->num_by_type[i], chunk_size_name(i), |
2078 stat->num_by_type[i], chunk_size_name(i), |
2065 stat->single_size_by_type[i], |
2079 stat->single_size_by_type[i]); |
2066 stat->total_size_by_type[i]); |
2080 if (scale == 1) { |
|
2081 out->print_cr(SIZE_FORMAT " bytes", stat->total_size_by_type[i]); |
|
2082 } else { |
|
2083 out->print_cr("%.2f%s", (float)stat->total_size_by_type[i] / scale, unit); |
|
2084 } |
|
2085 |
2067 total += stat->total_size_by_type[i]; |
2086 total += stat->total_size_by_type[i]; |
2068 } |
2087 } |
2069 out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes", |
2088 |
2070 stat->num_humongous_chunks, stat->total_size_humongous_chunks); |
2089 |
2071 total += stat->total_size_humongous_chunks; |
2090 total += stat->total_size_humongous_chunks; |
2072 out->print_cr(" total size: " SIZE_FORMAT ".", total); |
2091 |
2073 } |
2092 if (scale == 1) { |
2074 |
2093 out->print_cr(" " SIZE_FORMAT " humongous chunks, total " SIZE_FORMAT " bytes", |
2075 void ChunkManager::print_all_chunkmanagers(outputStream* out) { |
2094 stat->num_humongous_chunks, stat->total_size_humongous_chunks); |
|
2095 |
|
2096 out->print_cr(" total size: " SIZE_FORMAT " bytes.", total); |
|
2097 } else { |
|
2098 out->print_cr(" " SIZE_FORMAT " humongous chunks, total %.2f%s", |
|
2099 stat->num_humongous_chunks, |
|
2100 (float)stat->total_size_humongous_chunks / scale, unit); |
|
2101 |
|
2102 out->print_cr(" total size: %.2f%s.", (float)total / scale, unit); |
|
2103 } |
|
2104 |
|
2105 } |
|
2106 |
|
2107 void ChunkManager::print_all_chunkmanagers(outputStream* out, size_t scale) { |
|
2108 assert(scale == 1 || scale == K || scale == M || scale == G, "Invalid scale"); |
|
2109 |
2076 // Note: keep lock protection only to retrieving statistics; keep printing |
2110 // Note: keep lock protection only to retrieving statistics; keep printing |
2077 // out of lock protection |
2111 // out of lock protection |
2078 ChunkManagerStatistics stat; |
2112 ChunkManagerStatistics stat; |
2079 out->print_cr("Chunkmanager (non-class):"); |
2113 out->print_cr("Chunkmanager (non-class):"); |
2080 const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata(); |
2114 const ChunkManager* const non_class_cm = Metaspace::chunk_manager_metadata(); |
2081 if (non_class_cm != NULL) { |
2115 if (non_class_cm != NULL) { |
2082 non_class_cm->get_statistics(&stat); |
2116 non_class_cm->get_statistics(&stat); |
2083 ChunkManager::print_statistics(&stat, out); |
2117 ChunkManager::print_statistics(&stat, out, scale); |
2084 } else { |
2118 } else { |
2085 out->print_cr("unavailable."); |
2119 out->print_cr("unavailable."); |
2086 } |
2120 } |
2087 out->print_cr("Chunkmanager (class):"); |
2121 out->print_cr("Chunkmanager (class):"); |
2088 const ChunkManager* const class_cm = Metaspace::chunk_manager_class(); |
2122 const ChunkManager* const class_cm = Metaspace::chunk_manager_class(); |
2089 if (class_cm != NULL) { |
2123 if (class_cm != NULL) { |
2090 class_cm->get_statistics(&stat); |
2124 class_cm->get_statistics(&stat); |
2091 ChunkManager::print_statistics(&stat, out); |
2125 ChunkManager::print_statistics(&stat, out, scale); |
2092 } else { |
2126 } else { |
2093 out->print_cr("unavailable."); |
2127 out->print_cr("unavailable."); |
2094 } |
2128 } |
2095 } |
2129 } |
2096 |
2130 |
2978 small_waste, medium_count, medium_waste, humongous_count); |
3012 small_waste, medium_count, medium_waste, humongous_count); |
2979 if (Metaspace::using_class_space()) { |
3013 if (Metaspace::using_class_space()) { |
2980 print_class_waste(out); |
3014 print_class_waste(out); |
2981 } |
3015 } |
2982 } |
3016 } |
|
3017 |
|
3018 class MetadataStats VALUE_OBJ_CLASS_SPEC { |
|
3019 private: |
|
3020 size_t _capacity; |
|
3021 size_t _used; |
|
3022 size_t _free; |
|
3023 size_t _waste; |
|
3024 |
|
3025 public: |
|
3026 MetadataStats() : _capacity(0), _used(0), _free(0), _waste(0) { } |
|
3027 MetadataStats(size_t capacity, size_t used, size_t free, size_t waste) |
|
3028 : _capacity(capacity), _used(used), _free(free), _waste(waste) { } |
|
3029 |
|
3030 void add(const MetadataStats& stats) { |
|
3031 _capacity += stats.capacity(); |
|
3032 _used += stats.used(); |
|
3033 _free += stats.free(); |
|
3034 _waste += stats.waste(); |
|
3035 } |
|
3036 |
|
3037 size_t capacity() const { return _capacity; } |
|
3038 size_t used() const { return _used; } |
|
3039 size_t free() const { return _free; } |
|
3040 size_t waste() const { return _waste; } |
|
3041 |
|
3042 void print_on(outputStream* out, size_t scale) const; |
|
3043 }; |
|
3044 |
|
3045 |
|
3046 void MetadataStats::print_on(outputStream* out, size_t scale) const { |
|
3047 const char* unit = scale_unit(scale); |
|
3048 out->print_cr("capacity=%10.2f%s used=%10.2f%s free=%10.2f%s waste=%10.2f%s", |
|
3049 (float)capacity() / scale, unit, |
|
3050 (float)used() / scale, unit, |
|
3051 (float)free() / scale, unit, |
|
3052 (float)waste() / scale, unit); |
|
3053 } |
|
3054 |
|
3055 class PrintCLDMetaspaceInfoClosure : public CLDClosure { |
|
3056 private: |
|
3057 outputStream* _out; |
|
3058 size_t _scale; |
|
3059 |
|
3060 size_t _total_count; |
|
3061 MetadataStats _total_metadata; |
|
3062 MetadataStats _total_class; |
|
3063 |
|
3064 size_t _total_anon_count; |
|
3065 MetadataStats _total_anon_metadata; |
|
3066 MetadataStats _total_anon_class; |
|
3067 |
|
3068 public: |
|
3069 PrintCLDMetaspaceInfoClosure(outputStream* out, size_t scale = K) |
|
3070 : _out(out), _scale(scale), _total_count(0), _total_anon_count(0) { } |
|
3071 |
|
3072 ~PrintCLDMetaspaceInfoClosure() { |
|
3073 print_summary(); |
|
3074 } |
|
3075 |
|
3076 void do_cld(ClassLoaderData* cld) { |
|
3077 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); |
|
3078 |
|
3079 if (cld->is_unloading()) return; |
|
3080 Metaspace* msp = cld->metaspace_or_null(); |
|
3081 if (msp == NULL) { |
|
3082 return; |
|
3083 } |
|
3084 |
|
3085 bool anonymous = false; |
|
3086 if (cld->is_anonymous()) { |
|
3087 _out->print_cr("ClassLoader: for anonymous class"); |
|
3088 anonymous = true; |
|
3089 } else { |
|
3090 ResourceMark rm; |
|
3091 _out->print_cr("ClassLoader: %s", cld->loader_name()); |
|
3092 } |
|
3093 |
|
3094 print_metaspace(msp, anonymous); |
|
3095 _out->cr(); |
|
3096 } |
|
3097 |
|
3098 private: |
|
3099 void print_metaspace(Metaspace* msp, bool anonymous); |
|
3100 void print_summary() const; |
|
3101 }; |
|
3102 |
|
3103 void PrintCLDMetaspaceInfoClosure::print_metaspace(Metaspace* msp, bool anonymous){ |
|
3104 assert(msp != NULL, "Sanity"); |
|
3105 SpaceManager* vsm = msp->vsm(); |
|
3106 const char* unit = scale_unit(_scale); |
|
3107 |
|
3108 size_t capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord; |
|
3109 size_t used = vsm->sum_used_in_chunks_in_use() * BytesPerWord; |
|
3110 size_t free = vsm->sum_free_in_chunks_in_use() * BytesPerWord; |
|
3111 size_t waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord; |
|
3112 |
|
3113 _total_count ++; |
|
3114 MetadataStats metadata_stats(capacity, used, free, waste); |
|
3115 _total_metadata.add(metadata_stats); |
|
3116 |
|
3117 if (anonymous) { |
|
3118 _total_anon_count ++; |
|
3119 _total_anon_metadata.add(metadata_stats); |
|
3120 } |
|
3121 |
|
3122 _out->print(" Metadata "); |
|
3123 metadata_stats.print_on(_out, _scale); |
|
3124 |
|
3125 if (Metaspace::using_class_space()) { |
|
3126 vsm = msp->class_vsm(); |
|
3127 |
|
3128 capacity = vsm->sum_capacity_in_chunks_in_use() * BytesPerWord; |
|
3129 used = vsm->sum_used_in_chunks_in_use() * BytesPerWord; |
|
3130 free = vsm->sum_free_in_chunks_in_use() * BytesPerWord; |
|
3131 waste = vsm->sum_waste_in_chunks_in_use() * BytesPerWord; |
|
3132 |
|
3133 MetadataStats class_stats(capacity, used, free, waste); |
|
3134 _total_class.add(class_stats); |
|
3135 |
|
3136 if (anonymous) { |
|
3137 _total_anon_class.add(class_stats); |
|
3138 } |
|
3139 |
|
3140 _out->print(" Class data "); |
|
3141 class_stats.print_on(_out, _scale); |
|
3142 } |
|
3143 } |
|
3144 |
|
3145 void PrintCLDMetaspaceInfoClosure::print_summary() const { |
|
3146 const char* unit = scale_unit(_scale); |
|
3147 _out->cr(); |
|
3148 _out->print_cr("Summary:"); |
|
3149 |
|
3150 MetadataStats total; |
|
3151 total.add(_total_metadata); |
|
3152 total.add(_total_class); |
|
3153 |
|
3154 _out->print(" Total class loaders=" SIZE_FORMAT_W(6) " ", _total_count); |
|
3155 total.print_on(_out, _scale); |
|
3156 |
|
3157 _out->print(" Metadata "); |
|
3158 _total_metadata.print_on(_out, _scale); |
|
3159 |
|
3160 if (Metaspace::using_class_space()) { |
|
3161 _out->print(" Class data "); |
|
3162 _total_class.print_on(_out, _scale); |
|
3163 } |
|
3164 _out->cr(); |
|
3165 |
|
3166 MetadataStats total_anon; |
|
3167 total_anon.add(_total_anon_metadata); |
|
3168 total_anon.add(_total_anon_class); |
|
3169 |
|
3170 _out->print("For anonymous classes=" SIZE_FORMAT_W(6) " ", _total_anon_count); |
|
3171 total_anon.print_on(_out, _scale); |
|
3172 |
|
3173 _out->print(" Metadata "); |
|
3174 _total_anon_metadata.print_on(_out, _scale); |
|
3175 |
|
3176 if (Metaspace::using_class_space()) { |
|
3177 _out->print(" Class data "); |
|
3178 _total_anon_class.print_on(_out, _scale); |
|
3179 } |
|
3180 } |
|
3181 |
|
3182 void MetaspaceAux::print_metadata_for_nmt(outputStream* out, size_t scale) { |
|
3183 const char* unit = scale_unit(scale); |
|
3184 out->print_cr("Metaspaces:"); |
|
3185 out->print_cr(" Metadata space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s", |
|
3186 reserved_bytes(Metaspace::NonClassType) / scale, unit, |
|
3187 committed_bytes(Metaspace::NonClassType) / scale, unit); |
|
3188 if (Metaspace::using_class_space()) { |
|
3189 out->print_cr(" Class space: reserved=" SIZE_FORMAT_W(10) "%s committed=" SIZE_FORMAT_W(10) "%s", |
|
3190 reserved_bytes(Metaspace::ClassType) / scale, unit, |
|
3191 committed_bytes(Metaspace::ClassType) / scale, unit); |
|
3192 } |
|
3193 |
|
3194 out->cr(); |
|
3195 ChunkManager::print_all_chunkmanagers(out, scale); |
|
3196 |
|
3197 out->cr(); |
|
3198 out->print_cr("Per-classloader metadata:"); |
|
3199 out->cr(); |
|
3200 |
|
3201 PrintCLDMetaspaceInfoClosure cl(out, scale); |
|
3202 ClassLoaderDataGraph::cld_do(&cl); |
|
3203 } |
|
3204 |
2983 |
3205 |
2984 // Dump global metaspace things from the end of ClassLoaderDataGraph |
3206 // Dump global metaspace things from the end of ClassLoaderDataGraph |
2985 void MetaspaceAux::dump(outputStream* out) { |
3207 void MetaspaceAux::dump(outputStream* out) { |
2986 out->print_cr("All Metaspace:"); |
3208 out->print_cr("All Metaspace:"); |
2987 out->print("data space: "); print_on(out, Metaspace::NonClassType); |
3209 out->print("data space: "); print_on(out, Metaspace::NonClassType); |