1 /*******************************************************************************
2 * Copyright (c) 2016, 2017 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.nativemem;
14 import java.lang.reflect.InvocationTargetException;
16 import org.simantics.nativemem.internal.Arch;
17 import org.simantics.nativemem.internal.DummyProcessMemoryInfo;
18 import org.simantics.nativemem.internal.CMemoryInfo;
19 import org.simantics.nativemem.internal.OS;
20 import org.simantics.nativemem.internal.Resource;
21 import org.simantics.nativemem.internal.Resource32;
22 import org.simantics.nativemem.internal.Resource64;
23 import org.simantics.nativemem.internal.linux.Stat;
24 import org.simantics.nativemem.internal.win.ProcessMemoryCounters;
25 import org.simantics.nativemem.internal.win.Psapi32;
26 import org.simantics.nativemem.internal.win.Psapi64;
28 import com.sun.jna.platform.win32.Kernel32;
29 import com.sun.jna.platform.win32.WinNT.HANDLE;
32 * @author Tuukka Lehtonen
34 public class NativeMem {
38 * the structure to write the result into or <code>null</code> to
39 * create a new structure
40 * @return the result structure
42 public static ProcessMemoryInfo getMemoryInfo(ProcessMemoryInfo out) {
43 switch (OS.calculate()) {
45 return getProcessMemoryCounters(out);
48 return getCMemoryInfo(out);
51 CMemoryInfo info = getCMemoryInfo(out);
52 info.peakRSS *= 1024L;
58 return DummyProcessMemoryInfo.INSTANCE;
62 private static ProcessMemoryCounters getProcessMemoryCounters(ProcessMemoryInfo out) {
63 ProcessMemoryCounters counters = castOrCreate(out, ProcessMemoryCounters.class);
64 HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess();
65 switch (Arch.calculate()) {
67 Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX();
68 boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
70 pmem.writeTo(counters);
75 Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX();
76 boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
78 pmem.writeTo(counters);
87 private static CMemoryInfo getCMemoryInfo(ProcessMemoryInfo out) {
88 CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
90 switch (Arch.calculate()) {
92 Resource32.Rusage rusage = new Resource32.Rusage();
93 int ok = Resource32.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
100 Resource64.Rusage rusage = new Resource64.Rusage();
101 int ok = Resource64.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
103 rusage.writeTo(info);
112 private static CMemoryInfo getCurrentRSS(ProcessMemoryInfo out) {
113 CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
115 switch (Arch.calculate()) {
117 long rss = Stat.getCurrentRSS(Resource32.INSTANCE);
119 info.currentRSS = rss;
124 long rss = Stat.getCurrentRSS(Resource64.INSTANCE);
126 info.currentRSS = rss;
135 private static <T> T castOrCreate(Object o, Class<T> clazz) {
136 if (clazz.isInstance(o))
137 return clazz.cast(o);
139 return clazz.getConstructor().newInstance();
140 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
141 | NoSuchMethodException | SecurityException e) {
142 throw new Error("Class " + clazz + " does not have a public parameterless constructor", e);