diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 6b475c2546dea..7e4225d60b76f 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2139,7 +2139,7 @@ void os::Linux::print_system_memory_info(outputStream* st) { bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) { FILE* f = ::fopen("/proc/self/status", "r"); - const int num_values = 8; + const int num_values = sizeof(os::Linux::meminfo_t) / sizeof(size_t); int num_found = 0; char buf[256]; info->vmsize = info->vmpeak = info->vmrss = info->vmhwm = info->vmswap = @@ -2151,9 +2151,9 @@ bool os::Linux::query_process_memory_info(os::Linux::meminfo_t* info) { (info->vmswap == -1 && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &info->vmswap) == 1) || (info->vmhwm == -1 && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &info->vmhwm) == 1) || (info->vmrss == -1 && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &info->vmrss) == 1) || - (info->rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &info->rssanon) == 1) || - (info->rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &info->rssfile) == 1) || - (info->rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &info->rssshmem) == 1) + (info->rssanon == -1 && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &info->rssanon) == 1) || // Needs Linux 4.5 + (info->rssfile == -1 && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &info->rssfile) == 1) || // Needs Linux 4.5 + (info->rssshmem == -1 && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &info->rssshmem) == 1) // Needs Linux 4.5 ) { num_found ++; diff --git a/src/hotspot/os/linux/trimCHeapDCmd.cpp b/src/hotspot/os/linux/trimCHeapDCmd.cpp index 3879237fd4b1e..ee93ac5e8c8d7 100644 --- a/src/hotspot/os/linux/trimCHeapDCmd.cpp +++ b/src/hotspot/os/linux/trimCHeapDCmd.cpp @@ -36,9 +36,9 @@ void TrimCLibcHeapDCmd::execute(DCmdSource source, TRAPS) { #ifdef __GLIBC__ stringStream ss_report(1024); // Note: before calling trim - // Query memory before... os::Linux::meminfo_t info1; os::Linux::meminfo_t info2; + // Query memory before... bool have_info1 = os::Linux::query_process_memory_info(&info1); _output->print_cr("Attempting trim..."); @@ -49,25 +49,30 @@ void TrimCLibcHeapDCmd::execute(DCmdSource source, TRAPS) { bool have_info2 = os::Linux::query_process_memory_info(&info2); // Print report both to output stream as well to UL + bool wrote_something = false; if (have_info1 && have_info2) { if (info1.vmsize != -1 && info2.vmsize != -1) { ss_report.print_cr("Virtual size before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)", info1.vmsize, info2.vmsize, (info2.vmsize - info1.vmsize)); + wrote_something = true; } if (info1.vmrss != -1 && info2.vmrss != -1) { ss_report.print_cr("RSS before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)", info1.vmrss, info2.vmrss, (info2.vmrss - info1.vmrss)); + wrote_something = true; } if (info1.vmswap != -1 && info2.vmswap != -1) { ss_report.print_cr("Swap before: " SSIZE_FORMAT "k, after: " SSIZE_FORMAT "k, (" SSIZE_FORMAT "k)", info1.vmswap, info2.vmswap, (info2.vmswap - info1.vmswap)); + wrote_something = true; } - } else { + } + if (!wrote_something) { ss_report.print_raw("No details available."); } + _output->print_raw(ss_report.base()); - log_info(os)("malloc_trim: "); - log_info(os)("%s", ss_report.base()); + log_info(os)("malloc_trim:\n%s", ss_report.base()); #else _output->print_cr("Not available."); #endif diff --git a/src/hotspot/os/linux/trimCHeapDCmd.hpp b/src/hotspot/os/linux/trimCHeapDCmd.hpp index e9d2b4b32d3d1..3fe6375efdb53 100644 --- a/src/hotspot/os/linux/trimCHeapDCmd.hpp +++ b/src/hotspot/os/linux/trimCHeapDCmd.hpp @@ -34,10 +34,10 @@ class TrimCLibcHeapDCmd : public DCmd { public: TrimCLibcHeapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} static const char* name() { - return "VM.trim_libc_heap"; + return "System.glibc_trim_heap"; } static const char* description() { - return "Attempts to free up memory by trimming the glibc heap."; + return "Attempts to free up memory by trimming the glibc C-heap."; } static const char* impact() { return "Low"; diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index d8de7e9a87efb..f11026fe2f77b 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -96,7 +96,6 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - LINUX_ONLY(DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));) #if INCLUDE_SERVICES DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); @@ -121,6 +120,7 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #ifdef LINUX DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // LINUX DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); diff --git a/test/hotspot/jtreg/serviceability/dcmd/vm/TrimLibcHeapTest.java b/test/hotspot/jtreg/serviceability/dcmd/vm/TrimLibcHeapTest.java index 2621a52569e36..c79b35a12be6e 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/vm/TrimLibcHeapTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/vm/TrimLibcHeapTest.java @@ -40,9 +40,12 @@ */ public class TrimLibcHeapTest { public void run(CommandExecutor executor) { - OutputAnalyzer output = executor.execute("VM.trim_libc_heap"); + OutputAnalyzer output = executor.execute("System.glibc_trim_heap"); output.reportDiagnosticSummary(); - output.shouldMatch("(Done|Not available)"); + output.shouldMatch("(Done|Not available)"); // Not available could happen on Linux + non-glibc (eg. muslc) + if (output.firstMatch("Done") != null) { + output.shouldMatch("(Virtual size before|RSS before|Swap before|No details available)"); + } } @Test