Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/
package com.oracle.svm.core.genscavenge;

import com.oracle.svm.core.VMInspectionOptions;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.word.Pointer;
Expand All @@ -40,6 +41,8 @@
import com.oracle.svm.core.jdk.UninterruptibleUtils;
import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicUnsigned;
import com.oracle.svm.core.log.Log;
import com.oracle.svm.core.nmt.NmtCategory;
import com.oracle.svm.core.nmt.NativeMemoryTracking;
import com.oracle.svm.core.os.ChunkBasedCommittedMemoryProvider;
import com.oracle.svm.core.thread.VMOperation;
import com.oracle.svm.core.thread.VMThreads;
Expand Down Expand Up @@ -93,7 +96,10 @@ AlignedHeader produceAlignedChunk() {
if (result.isNull()) {
throw OutOfMemoryUtil.reportOutOfMemoryError(ALIGNED_OUT_OF_MEMORY_ERROR);
}

if (VMInspectionOptions.hasNativeMemoryTrackingSupport()) {
NativeMemoryTracking.singleton().trackReserve(chunkSize.rawValue(), NmtCategory.JavaHeap);
NativeMemoryTracking.singleton().trackCommit(chunkSize.rawValue(), NmtCategory.JavaHeap);
}
AlignedHeapChunk.initialize(result, chunkSize);
}
assert HeapChunk.getTopOffset(result).equal(AlignedHeapChunk.getObjectsStartOffset());
Expand Down Expand Up @@ -244,7 +250,10 @@ UnalignedHeader produceUnalignedChunk(UnsignedWord objectSize) {
if (result.isNull()) {
throw OutOfMemoryUtil.reportOutOfMemoryError(UNALIGNED_OUT_OF_MEMORY_ERROR);
}

if (VMInspectionOptions.hasNativeMemoryTrackingSupport()) {
NativeMemoryTracking.singleton().trackReserve(chunkSize.rawValue(), NmtCategory.JavaHeap);
NativeMemoryTracking.singleton().trackCommit(chunkSize.rawValue(), NmtCategory.JavaHeap);
}
UnalignedHeapChunk.initialize(result, chunkSize);
assert objectSize.belowOrEqual(HeapChunk.availableObjectMemory(result)) : "UnalignedHeapChunk insufficient for requested object";

Expand Down Expand Up @@ -306,12 +315,22 @@ static void freeUnalignedChunkList(UnalignedHeader first) {

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
private static void freeAlignedChunk(AlignedHeader chunk) {
ChunkBasedCommittedMemoryProvider.get().freeAlignedChunk(chunk, HeapParameters.getAlignedHeapChunkSize(), HeapParameters.getAlignedHeapChunkAlignment());
UnsignedWord size = HeapParameters.getAlignedHeapChunkSize();
ChunkBasedCommittedMemoryProvider.get().freeAlignedChunk(chunk, size, HeapParameters.getAlignedHeapChunkAlignment());
if (VMInspectionOptions.hasNativeMemoryTrackingSupport()) {
NativeMemoryTracking.singleton().trackUncommit(size.rawValue(), NmtCategory.JavaHeap);
NativeMemoryTracking.singleton().trackFree(size.rawValue(), NmtCategory.JavaHeap);
}
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
private static void freeUnalignedChunk(UnalignedHeader chunk) {
ChunkBasedCommittedMemoryProvider.get().freeUnalignedChunk(chunk, unalignedChunkSize(chunk));
UnsignedWord size = unalignedChunkSize(chunk);
ChunkBasedCommittedMemoryProvider.get().freeUnalignedChunk(chunk, size);
if (VMInspectionOptions.hasNativeMemoryTrackingSupport()) {
NativeMemoryTracking.singleton().trackUncommit(size.rawValue(), NmtCategory.JavaHeap);
NativeMemoryTracking.singleton().trackFree(size.rawValue(), NmtCategory.JavaHeap);
}
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public final class HeapImpl extends Heap {
/** Total number of times when threads waiting for a pending reference list were interrupted. */
private volatile long refListWaiterWakeUpCounter;

private volatile long imageHeapSize = -1;

/** Head of the linked list of object pins. */
private final AtomicReference<PinnedObjectImpl> pinHead = new AtomicReference<>();

Expand Down Expand Up @@ -475,6 +477,28 @@ public boolean walkImageHeapObjects(ObjectVisitor visitor) {
return !AuxiliaryImageHeap.isPresent() || AuxiliaryImageHeap.singleton().walkObjects(visitor);
}

@Override
public long getImageHeapSize() {
ImageHeapSizeVisitor visitor = new ImageHeapSizeVisitor();
if (imageHeapSize == -1) {
for (ImageHeapInfo info = firstImageHeapInfo; info != null; info = info.next) {
ImageHeapWalker.walkRegions(info, visitor);
}
imageHeapSize = visitor.size;
}
return imageHeapSize;
}

private static class ImageHeapSizeVisitor implements MemoryWalker.ImageHeapRegionVisitor {
long size;

@Override
public <T> boolean visitNativeImageHeapRegion(T region, MemoryWalker.NativeImageHeapRegionAccess<T> access) {
size += access.getSize(region).rawValue();
return true;
}
}

@Override
public boolean walkCollectedHeapObjects(ObjectVisitor visitor) {
VMOperation.guaranteeInProgressAtSafepoint("Must only be called at a safepoint");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ protected Heap() {
*/
public abstract boolean walkImageHeapObjects(ObjectVisitor visitor);

public abstract long getImageHeapSize();

/**
* Walk all heap objects except the native image heap objects. Must only be executed as part of
* a VM operation that causes a safepoint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,25 @@ private static void emitNativeMemoryTrackingEvents() {
private static void emitNmtPeakEvents() {
NativeMemoryUsageTotalPeakEvent nmtTotalPeakEvent = new NativeMemoryUsageTotalPeakEvent();

long totalPeakUsed = NativeMemoryTracking.singleton().getPeakTotalUsedMemory();
nmtTotalPeakEvent.peakCommitted = totalPeakUsed;
nmtTotalPeakEvent.peakReserved = totalPeakUsed;
nmtTotalPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtTotalPeakUsage();
long totalPeakMalloc = NativeMemoryTracking.singleton().getPeakTotalMallocMemory();
long totalPeakCommitted = NativeMemoryTracking.singleton().getPeakTotalCommittedVirtualMemory();
long totalPeakReserved = NativeMemoryTracking.singleton().getPeakTotalReservedVirtualMemory();

nmtTotalPeakEvent.peakCommitted = totalPeakCommitted + totalPeakMalloc;
nmtTotalPeakEvent.peakReserved = totalPeakReserved + totalPeakMalloc;
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);
nmtPeakEvent.peakCommitted = peakUsed;
nmtPeakEvent.peakReserved = peakUsed;
nmtPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtPeakUsage(nmtCategory);
long peakMalloc = NativeMemoryTracking.singleton().getPeakMallocMemory(nmtCategory);
long peakCommitted = NativeMemoryTracking.singleton().getPeakCommittedVirtualMemory(nmtCategory);
long peakReserved = NativeMemoryTracking.singleton().getPeakReservedVirtualMemory(nmtCategory);
nmtPeakEvent.peakCommitted = peakCommitted + peakMalloc;
nmtPeakEvent.peakReserved = peakReserved + peakMalloc;
nmtPeakEvent.countAtPeak = NativeMemoryTracking.singleton().getCountAtPeakMallocMemory(nmtCategory);
nmtPeakEvent.commit();
}
}
Expand All @@ -150,24 +155,27 @@ private static void emitJdkNmtEvents(NmtCategory[] nmtCategories) {

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

JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.NativeMemoryUsage);
JfrNativeEventWriter.putLong(data, timestamp);
JfrNativeEventWriter.putLong(data, nmtCategory.ordinal());
JfrNativeEventWriter.putLong(data, usedMemory); // reserved
JfrNativeEventWriter.putLong(data, usedMemory); // committed
JfrNativeEventWriter.putLong(data, mallocMemory + reservedVM);
JfrNativeEventWriter.putLong(data, mallocMemory + committedVM);
JfrNativeEventWriter.endSmallEvent(data);
}
}

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

long totalMallocMemory = NativeMemoryTracking.singleton().getTotalMallocMemory();
long totalCommittedVM = NativeMemoryTracking.singleton().getTotalCommittedVirtualMemory();
long totalReservedVM = NativeMemoryTracking.singleton().getTotalReservedVirtualMemory();
JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.NativeMemoryUsageTotal);
JfrNativeEventWriter.putLong(data, timestamp);
JfrNativeEventWriter.putLong(data, totalUsedMemory); // reserved
JfrNativeEventWriter.putLong(data, totalUsedMemory); // committed
JfrNativeEventWriter.putLong(data, totalMallocMemory + totalReservedVM);
JfrNativeEventWriter.putLong(data, totalMallocMemory + totalCommittedVM);
JfrNativeEventWriter.endSmallEvent(data);
}
}
Expand Down
Loading