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 public class NativeMem {
36 * the structure to write the result into or <code>null</code> to
37 * create a new structure
38 * @return the result structure
40 public static ProcessMemoryInfo getMemoryInfo(ProcessMemoryInfo out) {
41 switch (OS.calculate()) {
43 return getProcessMemoryCounters(out);
46 return getCMemoryInfo(out);
49 CMemoryInfo info = getCMemoryInfo(out);
50 info.peakRSS *= 1024L;
56 return DummyProcessMemoryInfo.INSTANCE;
60 private static ProcessMemoryCounters getProcessMemoryCounters(ProcessMemoryInfo out) {
61 ProcessMemoryCounters counters = castOrCreate(out, ProcessMemoryCounters.class);
62 HANDLE proc = Kernel32.INSTANCE.GetCurrentProcess();
63 switch (Arch.calculate()) {
65 Psapi32.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi32.PROCESS_MEMORY_COUNTERS_EX();
66 boolean ok = Psapi32.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
68 pmem.writeTo(counters);
73 Psapi64.PROCESS_MEMORY_COUNTERS_EX pmem = new Psapi64.PROCESS_MEMORY_COUNTERS_EX();
74 boolean ok = Psapi64.INSTANCE.GetProcessMemoryInfo(proc, pmem, pmem.size());
76 pmem.writeTo(counters);
85 private static CMemoryInfo getCMemoryInfo(ProcessMemoryInfo out) {
86 CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
88 switch (Arch.calculate()) {
90 Resource32.Rusage rusage = new Resource32.Rusage();
91 int ok = Resource32.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
98 Resource64.Rusage rusage = new Resource64.Rusage();
99 int ok = Resource64.INSTANCE.getrusage(Resource.RUSAGE_SELF, rusage);
101 rusage.writeTo(info);
110 private static CMemoryInfo getCurrentRSS(ProcessMemoryInfo out) {
111 CMemoryInfo info = castOrCreate(out, CMemoryInfo.class);
113 switch (Arch.calculate()) {
115 long rss = Stat.getCurrentRSS(Resource32.INSTANCE);
117 info.currentRSS = rss;
122 long rss = Stat.getCurrentRSS(Resource64.INSTANCE);
124 info.currentRSS = rss;
133 private static <T> T castOrCreate(Object o, Class<T> clazz) {
134 if (clazz.isInstance(o))
135 return clazz.cast(o);
137 return clazz.getConstructor().newInstance();
138 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
139 | NoSuchMethodException | SecurityException e) {
140 throw new Error("Class " + clazz + " does not have a public parameterless constructor", e);