Skip to content

Commit

Permalink
Account for vmem in JFR events and NMT report. Improve NMT report for…
Browse files Browse the repository at this point in the history
…mat.
  • Loading branch information
roberttoyonaga committed Jul 15, 2024
1 parent 555459b commit 8f65916
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,20 @@ private static void emitNativeMemoryTrackingEvents() {
private static void emitNmtPeakEvents() {
NativeMemoryUsageTotalPeakEvent nmtTotalPeakEvent = new NativeMemoryUsageTotalPeakEvent();

long totalPeakUsed = NativeMemoryTracking.singleton().getPeakTotalUsedMemory();
long totalPeakUsed = NativeMemoryTracking.singleton().getPeakTotalMallocMemory();
nmtTotalPeakEvent.peakCommitted = totalPeakUsed;
nmtTotalPeakEvent.peakReserved = totalPeakUsed;
nmtTotalPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtTotalPeakUsage();
nmtTotalPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtPeakTotalMallocMemory();
nmtTotalPeakEvent.commit();

for (NmtCategory nmtCategory : NmtCategory.values()) {
NativeMemoryUsagePeakEvent nmtPeakEvent = new NativeMemoryUsagePeakEvent();
nmtPeakEvent.type = nmtCategory.getName();

long peakUsed = NativeMemoryTracking.singleton().getPeakUsedMemory(nmtCategory);
long peakUsed = NativeMemoryTracking.singleton().getPeakMallocMemory(nmtCategory);
nmtPeakEvent.peakCommitted = peakUsed;
nmtPeakEvent.peakReserved = peakUsed;
nmtPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtPeakUsage(nmtCategory);
nmtPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtPeakMallocMemory(nmtCategory);
nmtPeakEvent.commit();
}
}
Expand All @@ -150,7 +150,7 @@ private static void emitJdkNmtEvents(NmtCategory[] nmtCategories) {

if (JfrEvent.NativeMemoryUsage.shouldEmit()) {
for (NmtCategory nmtCategory : nmtCategories) {
long usedMemory = NativeMemoryTracking.singleton().getUsedMemory(nmtCategory);
long usedMemory = NativeMemoryTracking.singleton().getMallocMemory(nmtCategory);

JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.NativeMemoryUsage);
JfrNativeEventWriter.putLong(data, timestamp);
Expand All @@ -162,7 +162,7 @@ private static void emitJdkNmtEvents(NmtCategory[] nmtCategories) {
}

if (JfrEvent.NativeMemoryUsageTotal.shouldEmit()) {
long totalUsedMemory = NativeMemoryTracking.singleton().getTotalUsedMemory();
long totalUsedMemory = NativeMemoryTracking.singleton().getTotalMallocMemory();

JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.NativeMemoryUsageTotal);
JfrNativeEventWriter.putLong(data, timestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
public class NativeMemoryTracking {
private static final UnsignedWord ALIGNMENT = WordFactory.unsigned(16);
private static final int MAGIC = 0xF0F1F2F3;
private static final long KB = 1024;

private final NmtMallocMemoryInfo[] mallocCategories;
private final NmtVirtualMemoryInfo[] virtualCategories;
Expand Down Expand Up @@ -208,54 +209,81 @@ void recordFree(UnsignedWord size, NmtCategory category) {
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getUsedMemory(NmtCategory category) {
public long getMallocMemory(NmtCategory category) {
return getMallocInfo(category).getUsed();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getPeakUsedMemory(NmtCategory category) {
public long getMallocCount(NmtCategory category) {
return getMallocInfo(category).getCount();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getPeakMallocMemory(NmtCategory category) {
return getMallocInfo(category).getPeakUsed();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getCountAtPeakUsage(NmtCategory category) {
public long getCountAtPeakMallocMemory(NmtCategory category) {
return getMallocInfo(category).getCountAtPeakUsage();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getTotalCount() {
public long getTotalMallocCount() {
return mallocTotal.getCount();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getTotalUsedMemory() {
public long getTotalMallocMemory() {
return mallocTotal.getUsed();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getPeakTotalUsedMemory() {
public long getPeakTotalMallocMemory() {
return mallocTotal.getPeakUsed();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getCountAtTotalPeakUsage() {
public long getCountAtPeakTotalMallocMemory() {
return mallocTotal.getCountAtPeakUsage();
}

public long getReservedByCategory(NmtCategory category) {
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getReservedVirtualMemory(NmtCategory category) {
return NativeMemoryTracking.singleton().getVirtualInfo(category).getReservedSize();
}

public long getCommittedByCategory(NmtCategory category) {
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getCommittedVirtualMemory(NmtCategory category) {
return getVirtualInfo(category).getCommittedSize();
}

public long getPeakCommittedByCategory(NmtCategory category) {
public long getPeakReservedVirtualMemory(NmtCategory category) {
return getVirtualInfo(category).getPeakReservedSize();
}

public long getPeakCommittedVirtualMemory(NmtCategory category) {
return getVirtualInfo(category).getPeakCommittedSize();
}

public long getPeakReservedByCategory(NmtCategory category) {
return getVirtualInfo(category).getPeakReservedSize();
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getTotalReservedVirtualMemory() {
return virtualTotal.getReservedSize();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getTotalCommittedVirtualMemory() {
return virtualTotal.getCommittedSize();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getPeakTotalReservedVirtualMemory() {
return virtualTotal.getPeakReservedSize();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getPeakTotalCommittedVirtualMemory() {
return virtualTotal.getPeakCommittedSize();
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
Expand Down Expand Up @@ -289,32 +317,43 @@ public static RuntimeSupport.Hook shutdownHook() {

private void printStatistics() {
if (VMInspectionOptions.PrintNMTStatistics.getValue()) {
System.out.println();
System.out.println("Native memory tracking");
System.out.println(" Peak total used memory: " + getPeakTotalUsedMemory() + " bytes");
System.out.println(" Peak Total committed memory: " + virtualTotal.getPeakCommittedSize() + " bytes");
System.out.println(" Peak Total reserved memory: " + virtualTotal.getPeakReservedSize() + " bytes");
System.out.println(" Total alive allocations at peak usage: " + getCountAtTotalPeakUsage());
System.out.println(" Total used memory: " + getTotalUsedMemory() + " bytes");
System.out.println(" Total alive allocations: " + getTotalCount());
System.out.println(" Total committed memory: " + virtualTotal.getCommittedSize() + " bytes");
System.out.println(" Total reserved memory: " + virtualTotal.getReservedSize() + " bytes");

for (int i = 0; i < NmtCategory.values().length; i++) {
String name = NmtCategory.values()[i].getName();
NmtMallocMemoryInfo info = getMallocInfo(i);
NmtVirtualMemoryInfo vMemInfo = getVirtualInfo(i);

System.out.println(" " + name + " peak used memory: " + info.getPeakUsed() + " bytes");
System.out.println(" " + name + " alive allocations at peak: " + info.getCountAtPeakUsage());
System.out.println(" " + name + " currently used memory: " + info.getUsed() + " bytes");
System.out.println(" " + name + " currently alive allocations: " + info.getCount());
System.out.println(" " + name + " committed memory: " + vMemInfo.getCommittedSize());
System.out.println(" " + name + " reserved memory: " + vMemInfo.getReservedSize());
System.out.println(" " + name + " peak committed memory: " + vMemInfo.getPeakCommittedSize());
System.out.println(" " + name + " peak reserved memory: " + vMemInfo.getPeakReservedSize());
}
System.out.println(generateReportString());
}
}

public String generateReportString() {

StringBuilder stringBuilder = new StringBuilder(3000);

stringBuilder.append("\n");
stringBuilder.append("Native memory tracking").append("\n\n");

stringBuilder.append("Total").append("\n");
long reservedTotal = (getTotalReservedVirtualMemory() + getTotalMallocMemory()) / KB;
long committedTotal = (getTotalCommittedVirtualMemory() + getTotalMallocMemory()) / KB;
stringBuilder.append("\t").append("(reserved=").append(reservedTotal).append("KB, committed=").append(committedTotal).append("KB)").append("\n");
stringBuilder.append("\t").append("(malloc=").append(getTotalMallocMemory() / KB).append("KB, count=").append(getTotalMallocCount()).append(")").append("\n");
stringBuilder.append("\t").append("(peak malloc=").append(getPeakTotalMallocMemory() / KB).append("KB, count at peak=").append(getCountAtPeakTotalMallocMemory()).append(")").append("\n");
stringBuilder.append("\t").append("(mmap: reserved=").append(getTotalReservedVirtualMemory() / KB).append("KB, committed=").append(getTotalCommittedVirtualMemory() / KB).append("KB)")
.append("\n");
stringBuilder.append("\t").append("(mmap: peak reserved=").append(getPeakTotalReservedVirtualMemory() / KB).append("KB, peak committed=").append(getPeakTotalCommittedVirtualMemory() / KB)
.append("KB)").append("\n");

for (int i = 0; i < NmtCategory.values().length; i++) {
NmtCategory category = NmtCategory.values()[i];
stringBuilder.append(category.getName()).append("\n");
long reserved = (getReservedVirtualMemory(category) + getMallocMemory(category)) / KB;
long committed = (getCommittedVirtualMemory(category) + getMallocMemory(category)) / KB;
stringBuilder.append("\t").append("(reserved=").append(reserved).append("KB, committed=").append(committed).append("KB)").append("\n");
stringBuilder.append("\t").append("(malloc=").append(getMallocMemory(category) / KB).append("KB, count=").append(getMallocCount(category)).append(")").append("\n");
stringBuilder.append("\t").append("(peak malloc=").append(getPeakMallocMemory(category) / KB).append("KB, count at peak=").append(getCountAtPeakMallocMemory(category)).append(")")
.append("\n");
stringBuilder.append("\t").append("(mmap: reserved=").append(getReservedVirtualMemory(category) / KB).append("KB, committed=").append(getCommittedVirtualMemory(category) / KB)
.append("KB)").append("\n");
stringBuilder.append("\t").append("(mmap: peak reserved=").append(getPeakReservedVirtualMemory(category) / KB).append("KB, peak committed=")
.append(getPeakCommittedVirtualMemory(category) / KB).append("KB)").append("\n");
}
return stringBuilder.toString();
}

private static void teardown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,22 @@ private static void updatePeak(long newSize, AtomicLong peakToUpdate) {
}
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
long getReservedSize() {
return reservedSize.get();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
long getCommittedSize() {
return committedSize.get();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
long getPeakReservedSize() {
return peakReservedSize.get();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
long getPeakCommittedSize() {
return peakCommittedSize.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ public void testPeakTracking() {
assertEquals(0, getUsedMemory());

Pointer ptr1 = NativeMemory.malloc(M, NmtCategory.Code);
long peakUsed = NativeMemoryTracking.singleton().getPeakUsedMemory(NmtCategory.Code);
long peakUsed = NativeMemoryTracking.singleton().getPeakMallocMemory(NmtCategory.Code);
assertEquals(M, peakUsed);

Pointer ptr2 = NativeMemory.malloc(M, NmtCategory.Code);
peakUsed = NativeMemoryTracking.singleton().getPeakUsedMemory(NmtCategory.Code);
peakUsed = NativeMemoryTracking.singleton().getPeakMallocMemory(NmtCategory.Code);
assertEquals(2 * M, peakUsed);

NativeMemory.free(ptr1);
Expand All @@ -108,21 +108,21 @@ public void testPeakTracking() {
ptr2 = WordFactory.nullPointer();

assertEquals(0, getUsedMemory());
assertEquals(2 * M, NativeMemoryTracking.singleton().getPeakUsedMemory(NmtCategory.Code));
assertEquals(2 * M, NativeMemoryTracking.singleton().getPeakMallocMemory(NmtCategory.Code));

Pointer ptr3 = NativeMemory.malloc(3 * M, NmtCategory.Code);
peakUsed = NativeMemoryTracking.singleton().getPeakUsedMemory(NmtCategory.Code);
peakUsed = NativeMemoryTracking.singleton().getPeakMallocMemory(NmtCategory.Code);
assertEquals(3 * M, peakUsed);

NativeMemory.free(ptr3);
ptr3 = WordFactory.nullPointer();

assertEquals(0, getUsedMemory());
assertEquals(3 * M, NativeMemoryTracking.singleton().getPeakUsedMemory(NmtCategory.Code));
assertEquals(3 * M, NativeMemoryTracking.singleton().getPeakMallocMemory(NmtCategory.Code));
}

private static long getUsedMemory() {
return NativeMemoryTracking.singleton().getUsedMemory(NmtCategory.Code);
return NativeMemoryTracking.singleton().getMallocMemory(NmtCategory.Code);
}

@Test
Expand Down Expand Up @@ -387,7 +387,7 @@ public void testReservedPeak() {
assertEquals("Test should start with no memory already allocated in the test category.", 0, getReserved());
assertEquals("Test should start with no memory already allocated in the test category.", 0, getCommitted());

long initialPeak = NativeMemoryTracking.singleton().getPeakReservedByCategory(NmtCategory.Code);
long initialPeak = NativeMemoryTracking.singleton().getPeakReservedVirtualMemory(NmtCategory.Code);

Pointer reservePtr1 = VirtualMemoryProvider.get().reserve(WordFactory.unsigned(initialPeak), GRANULARITY, false,
NmtCategory.Code);
Expand All @@ -396,34 +396,34 @@ public void testReservedPeak() {
Pointer reservePtr2 = VirtualMemoryProvider.get().reserve(WordFactory.unsigned(initialPeak), GRANULARITY, false,
NmtCategory.Code);
long peakReserved = getReserved();
assertEquals(peakReserved, NativeMemoryTracking.singleton().getPeakReservedByCategory(NmtCategory.Code));
assertEquals(peakReserved, NativeMemoryTracking.singleton().getPeakReservedVirtualMemory(NmtCategory.Code));

free(reservePtr1, initialPeak);
free(reservePtr2, initialPeak);

assertEquals(peakReserved, NativeMemoryTracking.singleton().getPeakReservedByCategory(NmtCategory.Code));
assertEquals(peakReserved, NativeMemoryTracking.singleton().getPeakReservedVirtualMemory(NmtCategory.Code));
assertEquals(0, getReserved());
}

@Test
public void testCommittedPeak() {
long initialPeak = NativeMemoryTracking.singleton().getPeakCommittedByCategory(NmtCategory.Code);
long initialPeak = NativeMemoryTracking.singleton().getPeakCommittedVirtualMemory(NmtCategory.Code);
long largeReserveSize = initialPeak * 2;
int largeCommitSize = (int) initialPeak;
Pointer reservePtr = VirtualMemoryProvider.get().reserve(WordFactory.unsigned(largeReserveSize), HeapParameters.getAlignedHeapChunkSize(), false,
NmtCategory.Code);

Pointer commitPtr1 = commit(reservePtr, largeCommitSize);
assertEquals(getCommitted(), NativeMemoryTracking.singleton().getPeakCommittedByCategory(NmtCategory.Code));
assertEquals(getCommitted(), NativeMemoryTracking.singleton().getPeakCommittedVirtualMemory(NmtCategory.Code));

Pointer commitPtr2 = commit(commitPtr1.add(largeCommitSize), largeCommitSize);
long recordedCommittedSize2 = getCommitted();
assertEquals(recordedCommittedSize2, NativeMemoryTracking.singleton().getPeakCommittedByCategory(NmtCategory.Code));
assertEquals(recordedCommittedSize2, NativeMemoryTracking.singleton().getPeakCommittedVirtualMemory(NmtCategory.Code));

uncommit(commitPtr1, largeCommitSize);
uncommit(commitPtr2, largeCommitSize);
assertEquals(0, getCommitted());
assertEquals(recordedCommittedSize2, NativeMemoryTracking.singleton().getPeakCommittedByCategory(NmtCategory.Code));
assertEquals(recordedCommittedSize2, NativeMemoryTracking.singleton().getPeakCommittedVirtualMemory(NmtCategory.Code));

free(reservePtr, largeReserveSize);
assertEquals(0, getReserved());
Expand All @@ -447,11 +447,11 @@ private static void free(PointerBase start, long nbytes) {
}

private static long getReserved() {
return NativeMemoryTracking.singleton().getReservedByCategory(NmtCategory.Code);
return NativeMemoryTracking.singleton().getReservedVirtualMemory(NmtCategory.Code);
}

private static long getCommitted() {
return NativeMemoryTracking.singleton().getCommittedByCategory(NmtCategory.Code);
return NativeMemoryTracking.singleton().getCommittedVirtualMemory(NmtCategory.Code);
}

private static Pointer beginVirtualMemoryTestAndReserve() {
Expand Down

0 comments on commit 8f65916

Please sign in to comment.