diff --git a/src/hotspot/share/nmt/memReporter.cpp b/src/hotspot/share/nmt/memReporter.cpp index b09cf7ae2bd..d53782dfdaa 100644 --- a/src/hotspot/share/nmt/memReporter.cpp +++ b/src/hotspot/share/nmt/memReporter.cpp @@ -487,7 +487,35 @@ void MemSummaryDiffReporter::report_diff() { print_virtual_memory_diff(_current_baseline.total_reserved_memory(), _current_baseline.total_committed_memory(), _early_baseline.total_reserved_memory(), _early_baseline.total_committed_memory()); + out->cr(); + out->cr(); + // malloc diff + const size_t early_malloced_bytes = + _early_baseline.malloc_memory_snapshot()->total(); + const size_t early_count = + _early_baseline.malloc_memory_snapshot()->total_count(); + const size_t current_malloced_bytes = + _current_baseline.malloc_memory_snapshot()->total(); + const size_t current_count = + _current_baseline.malloc_memory_snapshot()->total_count(); + print_malloc_diff(current_malloced_bytes, current_count, early_malloced_bytes, + early_count, mtNone); + out->cr(); + out->cr(); + + // mmap diff + out->print("mmap: "); + const size_t early_reserved = + _early_baseline.virtual_memory_snapshot()->total_reserved(); + const size_t early_committed = + _early_baseline.virtual_memory_snapshot()->total_committed(); + const size_t current_reserved = + _current_baseline.virtual_memory_snapshot()->total_reserved(); + const size_t current_committed = + _current_baseline.virtual_memory_snapshot()->total_committed(); + print_virtual_memory_diff(current_reserved, current_committed, early_reserved, + early_committed); out->cr(); out->cr(); diff --git a/test/hotspot/jtreg/runtime/NMT/TotalMallocMmapDiffTest.java b/test/hotspot/jtreg/runtime/NMT/TotalMallocMmapDiffTest.java new file mode 100644 index 00000000000..3ba94c6a31a --- /dev/null +++ b/test/hotspot/jtreg/runtime/NMT/TotalMallocMmapDiffTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Red Hat Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8332125 + * @summary Test to verify correctness of total malloc and mmap diffs + * @key randomness + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary -Xms32m -Xmx32m TotalMallocMmapDiffTest + * + */ + +import jdk.test.lib.process.OutputAnalyzer; + +import jdk.test.whitebox.WhiteBox; + +public class TotalMallocMmapDiffTest { + private static final WhiteBox wb = WhiteBox.getWhiteBox(); + private static final long ALLOCATE_SIZE = 250 * 1024 * 1024; // 250MB + private static final double FUDGE_FACTOR = 0.2; + private static final double UPPER_BOUND = ALLOCATE_SIZE * (1 + FUDGE_FACTOR); + private static final double LOWER_BOUND = ALLOCATE_SIZE * (1 - FUDGE_FACTOR); + + public static void main(String[] args) throws Exception { + + // Get baseline + OutputAnalyzer output = NMTTestUtils.startJcmdVMNativeMemory("baseline=true", "scale=1"); + output.shouldContain("Baseline taken"); + + // Allocate some memory via malloc + long addr = wb.NMTMalloc(ALLOCATE_SIZE); + + // Virtually reserve and commit memory + addr = wb.NMTReserveMemory(ALLOCATE_SIZE); + wb.NMTCommitMemory(addr, ALLOCATE_SIZE); + + // Get NMT diff + output = NMTTestUtils.startJcmdVMNativeMemory("summary.diff", "scale=1"); + + // Verify malloc diff accounts for memory allocation with a fudge factor + long mallocDiff = getMallocDiff(output); + if (mallocDiff < LOWER_BOUND || mallocDiff > UPPER_BOUND) { + throw new Exception("Total malloc diff is incorrect. " + + "Expected malloc diff range: [" + LOWER_BOUND + " - " + UPPER_BOUND + "]" + + "Actual malloc diff: " + mallocDiff); + } + + // Verify mmap diff accounts for reserve and commit + long reservedDiff = getReservedDiff(output); + long committedDiff = getCommittedDiff(output); + if (reservedDiff < LOWER_BOUND || reservedDiff > UPPER_BOUND) { + throw new Exception("mmap reserved diff is incorrect. " + + "Expected reserved diff range: [" + LOWER_BOUND + " - " + UPPER_BOUND + "]" + + "Actual reserved diff: " + reservedDiff); + } + if (committedDiff < LOWER_BOUND || committedDiff > UPPER_BOUND) { + throw new Exception("mmap committed diff is incorrect. " + + "Expected committed diff range: [" + LOWER_BOUND + " - " + UPPER_BOUND + "]" + + "Actual committed diff: " + committedDiff); + } + + } + + private static long getMallocDiff(OutputAnalyzer output) { + // First match should be global malloc diff + String malloc = output.firstMatch("malloc=\\d+ \\+(\\d+)", 1); + return Long.parseLong(malloc); + } + + private static long getReservedDiff(OutputAnalyzer output) { + // First match should be global mmap diff + String reservedDiff = output.firstMatch("mmap: reserved=\\d+ \\+(\\d+)", 1); + return Long.parseLong(reservedDiff); + } + + private static long getCommittedDiff(OutputAnalyzer output) { + // First match should be global mmap diff + String committedDiff = output.firstMatch("mmap: reserved=\\d+ \\+\\d+, committed=\\d+ \\+(\\d+)", 1); + return Long.parseLong(committedDiff); + } +}