From ea17057d1c483f8a2bcb765527e45cf4fba36df5 Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Sun, 23 Apr 2017 13:23:43 +0300 Subject: [PATCH] Allow tab-separated columnized logging of memory use refs #7166 Change-Id: I6a7f38757db1c3cfcd0d04cfedfd963fde4c5a4d --- .../org/simantics/nativemem/NativeMem.java | 4 +- .../nativemem/ProcessMemoryInfo.java | 17 +++++++- .../nativemem/internal/CMemoryInfo.java | 23 ++++++++-- .../internal/DummyProcessMemoryInfo.java | 12 +++++- .../simantics/nativemem/internal/Util.java | 10 ++++- .../internal/win/ProcessMemoryCounters.java | 42 ++++++++++++++----- 6 files changed, 89 insertions(+), 19 deletions(-) diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java index bf7613803..5f7190f08 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/NativeMem.java @@ -28,7 +28,9 @@ import org.simantics.nativemem.internal.win.Psapi64; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT.HANDLE; - +/** + * @author Tuukka Lehtonen + */ public class NativeMem { /** diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryInfo.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryInfo.java index fb7a17a61..29eabb07f 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryInfo.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/ProcessMemoryInfo.java @@ -19,6 +19,21 @@ package org.simantics.nativemem; */ public interface ProcessMemoryInfo { - public String toHumanReadableString(); + /** + * @return a non-structured human readable string representation of this instances contents + */ + String toHumanReadableString(); + + /** + * @return tab-separated row of text containing N columns of explanatory + * header text for writing a tab-separated "CSV" file + */ + String headerRow(); + + /** + * @return tab-separated row of text containing N columns of data values + * that match the explanations provided by {@link #headerRow()} + */ + String dataRow(); } \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/CMemoryInfo.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/CMemoryInfo.java index aca7fa9e5..7412a73ff 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/CMemoryInfo.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/CMemoryInfo.java @@ -28,12 +28,29 @@ public class CMemoryInfo implements ProcessMemoryInfo { + peakRSS + "]"; } + @Override public String toHumanReadableString() { StringBuilder sb = new StringBuilder(); - sb.append("Memory Use [Current RSS = ").append(currentRSS) - .append(" MB, Peak RSS = ").append(Util.toMb(peakRSS)) - .append(" MB]"); + sb.append("RSS ").append(Util.toMb(currentRSS)) + .append("M / ").append(Util.toMb(peakRSS)) + .append("M"); return sb.toString(); } + @Override + public String headerRow() { + return "RSS [MB]\tPeak RSS [MB]"; + } + + @Override + public String dataRow() { + return Util.toMb(currentRSS) + "\t" + Util.toMb(peakRSS); + } + + public static void main(String[] args) { + System.out.println(new CMemoryInfo().toHumanReadableString()); + System.out.println(new CMemoryInfo().headerRow()); + System.out.println(new CMemoryInfo().dataRow()); + } + } \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/DummyProcessMemoryInfo.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/DummyProcessMemoryInfo.java index 8f001c47b..032d4fb5d 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/DummyProcessMemoryInfo.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/DummyProcessMemoryInfo.java @@ -21,7 +21,17 @@ public enum DummyProcessMemoryInfo implements ProcessMemoryInfo { @Override public String toHumanReadableString() { - return "Memory consumption information not available for this platform (" + OS.calculate() + "; " + Arch.calculate() + ")"; + return "Native process memory consumption information not available for this platform (" + OS.calculate() + "; " + Arch.calculate() + ")"; + } + + @Override + public String headerRow() { + return ""; + } + + @Override + public String dataRow() { + return ""; } } diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Util.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Util.java index fcfb07f18..666537630 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Util.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/Util.java @@ -16,8 +16,14 @@ package org.simantics.nativemem.internal; */ public class Util { - public static double toMb(long bytes) { - return (double) bytes / 1048576.0; + public static final String NL = String.format("%n"); + + public static long toMb(long numBytes) { + return (numBytes + (512 * 1024)) / (1024 * 1024); + } + + public static long toKb(long numBytes) { + return (numBytes + 512) / 1024; } } \ No newline at end of file diff --git a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/win/ProcessMemoryCounters.java b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/win/ProcessMemoryCounters.java index 9c68a5448..9f9129aab 100644 --- a/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/win/ProcessMemoryCounters.java +++ b/bundles/org.simantics.nativemem/src/org/simantics/nativemem/internal/win/ProcessMemoryCounters.java @@ -45,20 +45,40 @@ public class ProcessMemoryCounters implements ProcessMemoryInfo { + PeakPagefileUsage + ", PrivateUsage=" + PrivateUsage + "]"; } + @Override public String toHumanReadableString() { StringBuilder sb = new StringBuilder(); - sb.append("ProcessMemoryCounters [\n\tPageFaultCount = ").append(PageFaultCount) - .append(",\n\tPeakWorkingSetSize = ").append(Util.toMb(PeakWorkingSetSize)) - .append(" MB,\n\tWorkingSetSize = ").append(Util.toMb(WorkingSetSize)) - .append(" MB,\n\tQuotaPeakPagedPoolUsage = ").append(Util.toMb(QuotaPeakPagedPoolUsage)) - .append(" MB,\n\tQuotaPagedPoolUsage = ").append(Util.toMb(QuotaPagedPoolUsage)) - .append(" MB,\n\tQuotaPeakNonPagedPoolUsage = ").append(Util.toMb(QuotaPeakNonPagedPoolUsage)) - .append(" MB,\n\tQuotaNonPagedPoolUsage = ").append(Util.toMb(QuotaNonPagedPoolUsage)) - .append(" MB,\n\tPagefileUsage = ").append(Util.toMb(PagefileUsage)) - .append(" MB,\n\tPeakPagefileUsage = ").append(Util.toMb(PeakPagefileUsage)) - .append(" MB,\n\tPrivateUsage = ").append(Util.toMb(PrivateUsage)) - .append(" MB]"); + sb.append("RSS ").append(Util.toMb(WorkingSetSize)) + .append("M / ").append(Util.toMb(PeakWorkingSetSize)) + .append("M").append(Util.NL) + .append("Paged/Nonpaged Pool ").append(Util.toKb(QuotaPagedPoolUsage)).append("K / ") + .append(Util.toKb(QuotaPeakPagedPoolUsage)).append("K / ") + .append(Util.toKb(QuotaNonPagedPoolUsage)).append("K / ") + .append(Util.toKb(QuotaPeakNonPagedPoolUsage)).append("K").append(Util.NL) + .append("Page File ").append(Util.toMb(PagefileUsage)) + .append("M / ").append(Util.toMb(PeakPagefileUsage)) + .append("M (").append(PageFaultCount).append(" faults)"); return sb.toString(); } + @Override + public String headerRow() { + return "RSS [MB]\tPeak RSS [MB]\tPaged Pool Usage [kB]\tPeak Paged Pool Usage [kB]\tNonpaged Pool Usage [kB]\tPeak Nonpaged Pool Usage [kB]\tPage File Usage [MB]\tPeak Page File Usage [MB]\tPage Faults"; + } + + @Override + public String dataRow() { + return Util.toMb(WorkingSetSize) + "\t" + Util.toMb(PeakWorkingSetSize) + + "\t" + Util.toKb(QuotaPagedPoolUsage) + "\t" + Util.toKb(QuotaPeakPagedPoolUsage) + + "\t" + Util.toKb(QuotaNonPagedPoolUsage) + "\t" + Util.toKb(QuotaPeakNonPagedPoolUsage) + + "\t" + Util.toMb(PagefileUsage) + "\t" + Util.toMb(PeakPagefileUsage) + + "\t" + PageFaultCount; + } + + public static void main(String[] args) { + System.out.println(new ProcessMemoryCounters().toHumanReadableString()); + System.out.println(new ProcessMemoryCounters().headerRow()); + System.out.println(new ProcessMemoryCounters().dataRow()); + } + } \ No newline at end of file -- 2.43.2