Skip to content
Permalink
Browse files
8277383: VM.metaspace optionally show chunk freelist details
Backport-of: 35361270cb3aae9fa560736f8d05f1b258704c87
  • Loading branch information
tstuefe committed Feb 23, 2022
1 parent 9bb8b7f commit 0c6e662f0a2daae12f2ab2a840941bdcae0ca22e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
@@ -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"),
@@ -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);
}

@@ -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);
}
@@ -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:
@@ -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();
@@ -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
@@ -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());

1 comment on commit 0c6e662

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 0c6e662 Feb 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.