Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap) :
_by_spacetype("by-spacetype", "Break down numbers by loader type.", "BOOLEAN", false, "false"),
_by_chunktype("by-chunktype", "Break down numbers by chunk type.", "BOOLEAN", false, "false"),
_show_vslist("vslist", "Shows details about the underlying virtual space.", "BOOLEAN", false, "false"),
_show_chunkfreelist("chunkfreelist", "Shows details about global chunk free lists (ChunkManager).", "BOOLEAN", false, "false"),
_scale("scale", "Memory usage in which to scale. Valid values are: 1, KB, MB or GB (fixed scale) "
"or \"dynamic\" for a dynamically choosen scale.",
"STRING", false, "dynamic"),
Expand All @@ -53,6 +54,7 @@ MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap) :
_dcmdparser.add_dcmd_option(&_by_chunktype);
_dcmdparser.add_dcmd_option(&_by_spacetype);
_dcmdparser.add_dcmd_option(&_show_vslist);
_dcmdparser.add_dcmd_option(&_show_chunkfreelist);
_dcmdparser.add_dcmd_option(&_scale);
}

Expand Down Expand Up @@ -96,6 +98,7 @@ void MetaspaceDCmd::execute(DCmdSource source, TRAPS) {
if (_by_chunktype.value()) flags |= (int)MetaspaceReporter::Option::BreakDownByChunkType;
if (_by_spacetype.value()) flags |= (int)MetaspaceReporter::Option::BreakDownBySpaceType;
if (_show_vslist.value()) flags |= (int)MetaspaceReporter::Option::ShowVSList;
if (_show_chunkfreelist.value()) flags |= (int)MetaspaceReporter::Option::ShowChunkFreeList;
VM_PrintMetadata op(output(), scale, flags);
VMThread::execute(&op);
}
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class MetaspaceDCmd : public DCmdWithParser {
DCmdArgument<bool> _by_spacetype;
DCmdArgument<bool> _by_chunktype;
DCmdArgument<bool> _show_vslist;
DCmdArgument<bool> _show_chunkfreelist;
DCmdArgument<char*> _scale;
DCmdArgument<bool> _show_classes;
public:
Expand Down
18 changes: 18 additions & 0 deletions src/hotspot/share/memory/metaspace/metaspaceReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,24 @@ void MetaspaceReporter::print_report(outputStream* out, size_t scale, int flags)
out->cr();
}

// -- Print Chunkmanager details.
if ((flags & (int)Option::ShowChunkFreeList) > 0) {
out->cr();
out->print_cr("Chunk freelist details:");
if (Metaspace::using_class_space()) {
out->print_cr(" Non-Class:");
}
ChunkManager::chunkmanager_nonclass()->print_on(out);
out->cr();
if (Metaspace::using_class_space()) {
out->print_cr(" Class:");
ChunkManager::chunkmanager_class()->print_on(out);
out->cr();
}
}
out->cr();


//////////// Waste section ///////////////////////////
// As a convenience, print a summary of common waste.
out->cr();
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/memory/metaspace/metaspaceReporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class MetaspaceReporter : public AllStatic {
// Print details about the underlying virtual spaces.
ShowVSList = (1 << 3),
// If show_loaders: show loaded classes for each loader.
ShowClasses = (1 << 4)
ShowClasses = (1 << 4),
// Print details about the underlying virtual spaces.
ShowChunkFreeList = (1 << 5)
};

// This will print out a basic metaspace usage report but
Expand Down
23 changes: 23 additions & 0 deletions test/hotspot/jtreg/runtime/Metaspace/PrintMetaspaceDcmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,29 @@ private static void doTheCCSPropTest(boolean usesCompressedClassSpace) throws Ex
output.shouldContain("Virtual space list");
output.shouldMatch("node.*reserved.*committed.*used.*");

pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "chunkfreelist"});
// Output should look somewhat like this...
// vvvvvvvvvvvvvvvv
// Chunk freelist details:
// Non-Class:
// cm non-class-space: 5 chunks, total word size: 402944.
// -- List[lv00]: empty
// -- List[lv01]: - <Chunk @0x00007f925c124090, state f, base 0x00007f9208600000, level lv01 (262144 words), used 0 words, committed 0 words.> - total : 1 chunks.
// -- List[lv02]: - <Chunk @0x00007f925c1240d8, state f, base 0x00007f9208500000, level lv02 (131072 words), used 0 words, committed 0 words.> - total : 1 chunks.
// -- List[lv03]: empty
// .....
//
// total chunks: 5, total word size: 402944.
// ^^^^^^^^^^^^^^^^^
// .... but the actual number of chunks in the freelist is difficult to predict and may be low or zero since
// no class unloading happened yet.
output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
output.shouldContain("Chunk freelist details:");
// ... but we should see at least one one chunk somewhere, the list should never be empty.
output.shouldMatch(".*-- List\\[lv00\\].*");
output.shouldMatch(".*total chunks.*total word size.*");

// Test with different scales
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.metaspace", "scale=G"});
output = new OutputAnalyzer(pb.start());
Expand Down