Skip to content

Commit 6829d9a

Browse files
Sonia Zaldana Calleststuefe
authored andcommitted
8332122: [nmt] Totals for malloc should show total peak
Reviewed-by: stuefe, jsjolen
1 parent 9d332e6 commit 6829d9a

File tree

3 files changed

+117
-2
lines changed

3 files changed

+117
-2
lines changed

src/hotspot/share/nmt/mallocTracker.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,16 @@ class MallocMemorySnapshot {
179179
return _all_mallocs.size() + malloc_overhead() + total_arena();
180180
}
181181

182+
// Total peak malloc
183+
size_t total_peak() const {
184+
return _all_mallocs.peak_size();
185+
}
186+
187+
// Total peak count
188+
size_t total_peak_count() const {
189+
return _all_mallocs.peak_count();
190+
}
191+
182192
// Total malloc'd memory used by arenas
183193
size_t total_arena() const;
184194

src/hotspot/share/nmt/memReporter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,11 @@ void MemSummaryReporter::report() {
165165
out->print("Total: ");
166166
print_total(total_reserved_amount, total_committed_amount);
167167
out->cr();
168-
out->print_cr(" malloc: " SIZE_FORMAT "%s #" SIZE_FORMAT,
168+
out->print_cr(" malloc: " SIZE_FORMAT "%s #" SIZE_FORMAT ", peak=" SIZE_FORMAT "%s #" SIZE_FORMAT,
169169
amount_in_current_scale(total_malloced_bytes), current_scale(),
170-
_malloc_snapshot->total_count());
170+
_malloc_snapshot->total_count(),
171+
amount_in_current_scale(_malloc_snapshot->total_peak()),
172+
current_scale(), _malloc_snapshot->total_peak_count());
171173
out->print(" mmap: ");
172174
print_total(total_mmap_reserved_bytes, total_mmap_committed_bytes);
173175
out->cr();
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2024, Red Hat Inc.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
/*
26+
* @test
27+
* @bug 8332122
28+
* @summary Test to verify correctness of peak malloc tracking
29+
* @key randomness
30+
* @library /test/lib
31+
* @modules java.base/jdk.internal.misc
32+
* java.management
33+
* @build jdk.test.whitebox.WhiteBox
34+
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
35+
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary -Xms32m -Xmx32m -Xint PeakMallocTest
36+
*
37+
*/
38+
39+
// Note we run the test with -Xint to keep compilers from running and reduce malloc noise.
40+
41+
import jdk.test.lib.process.OutputAnalyzer;
42+
43+
import jdk.test.whitebox.WhiteBox;
44+
45+
public class PeakMallocTest {
46+
47+
private static WhiteBox wb = WhiteBox.getWhiteBox();
48+
private static final double FUDGE_FACTOR = 0.2;
49+
50+
public static void main(String[] args) throws Exception {
51+
52+
// Measure early malloc total and peak
53+
OutputAnalyzer output = NMTTestUtils.startJcmdVMNativeMemory("scale=1");
54+
long earlyTotal = getMallocTotal(output);
55+
long earlyPeak = getMallocPeak(output);
56+
System.out.println("Early malloc total: " + earlyTotal);
57+
System.out.println("Early malloc peak: " + earlyPeak);
58+
59+
// Allocate a large amount of memory and then free
60+
long allocSize = Math.max(8 * earlyPeak, 250 * 1024 * 1024); // MAX(earlyPeak * 8, 250MB)
61+
long addr = wb.NMTMalloc(allocSize);
62+
System.out.println("Allocation size: " + allocSize);
63+
wb.NMTFree(addr);
64+
65+
// Measure again
66+
output = NMTTestUtils.startJcmdVMNativeMemory("scale=1");
67+
long currTotal = getMallocTotal(output);
68+
long currPeak = getMallocPeak(output);
69+
System.out.println("Current malloc total: " + currTotal);
70+
System.out.println("Current malloc peak: " + currPeak);
71+
72+
// Verify total global malloc is similar with a fudge factor
73+
double mallocLowerBound = earlyTotal * (1 - FUDGE_FACTOR);
74+
double mallocUpperBound = earlyTotal * (1 + FUDGE_FACTOR);
75+
if (currTotal < mallocLowerBound || currTotal > mallocUpperBound) {
76+
throw new Exception("Global malloc measurement is incorrect. " +
77+
"Expected range: [" + mallocLowerBound + " - " + mallocUpperBound + "]. " +
78+
"Actual malloc total: " + currTotal);
79+
}
80+
81+
// Verify global malloc peak reflects large allocation with a fudge factor
82+
long peakDiff = currPeak - earlyPeak;
83+
double peakLowerBound = allocSize * (1 - FUDGE_FACTOR);
84+
double peakUpperBound = allocSize * (1 + FUDGE_FACTOR);
85+
if (peakDiff < peakLowerBound || peakDiff > peakUpperBound) {
86+
throw new Exception("Global malloc peak measurement is incorrect. " +
87+
"Expected peak diff range: [" + peakLowerBound + " - " + peakUpperBound + "]. " +
88+
"Actual peak diff: " + peakDiff);
89+
}
90+
}
91+
92+
private static long getMallocPeak(OutputAnalyzer output) {
93+
// First match should correspond to global malloc peak
94+
String global = output.firstMatch("peak=\\d*");
95+
return Long.parseLong(global.substring(global.indexOf("=") + 1));
96+
}
97+
98+
private static long getMallocTotal(OutputAnalyzer output) {
99+
// First match should correspond to global malloc total
100+
String global = output.firstMatch("malloc: \\d*");
101+
return Long.parseLong(global.substring(global.indexOf(" ") + 1));
102+
}
103+
}

0 commit comments

Comments
 (0)