Last active
July 10, 2020 10:25
-
-
Save vladimir-bukhtoyarov/314c4080368bb5ba0acdcc7e5cb88304 to your computer and use it in GitHub Desktop.
/proc/PID/smaps Parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SProcMapParserExample { | |
private static InputStream stream = SProcMapParserExample.class.getResourceAsStream("/some_dump_of_proc_maps.txt"); | |
public static class AllStat { | |
public static void main(String[] args) throws IOException { | |
SProcMap map = ProcSMapsParser.parse(stream); | |
List<ProcSMapItem> items = map.getItems(); | |
Collections.sort(items, Comparator.comparingLong(item -> item.getAttributes().get("Rss"))); | |
Collections.reverse(items); | |
print(items); | |
} | |
} | |
public static class MappedFilesStat { | |
public static void main(String[] args) throws IOException { | |
SProcMap map = ProcSMapsParser.parse(stream); | |
List<ProcSMapItem> items = map.getItems().stream() | |
.filter(item -> item.getInode() != 0L) | |
.collect(Collectors.toList()); | |
Collections.sort(items, Comparator.comparingLong(item -> item.getAttributes().get("Rss"))); | |
Collections.reverse(items); | |
print(items); | |
} | |
} | |
public static class AnonymousStat { | |
public static void main(String[] args) throws IOException { | |
SProcMap map = ProcSMapsParser.parse(stream); | |
List<ProcSMapItem> items = map.getItems().stream() | |
.filter(item -> item.getInode() == 0L) | |
.collect(Collectors.toList()); | |
Collections.sort(items, Comparator.comparingLong(item -> item.getAttributes().get("Rss"))); | |
Collections.reverse(items); | |
print(items); | |
} | |
} | |
private static void print(List<ProcSMapItem> items) { | |
AtomicLong runningSum = new AtomicLong(); | |
AtomicLong i = new AtomicLong(); | |
for (ProcSMapItem item : items) { | |
long rss = item.getAttributes().get("Rss") * 1024; | |
long size = item.getAttributes().get("Size") * 1024; | |
runningSum.addAndGet(rss); | |
i.incrementAndGet(); | |
System.out.printf("#%04d running-rss=%-,16d rss=%-,16d size=%-,16d device=%s %s %s-%s path=%s%n", i.get(), runningSum.get(), rss, size, item.getDevice(), item.getPermissions(), item.getBeginAddressStr(), item.getEndAddressStr(), item.getPathname()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.math.BigInteger; | |
import java.util.Map; | |
public class ProcSMapItem { | |
private final String beginAddressStr; | |
private final BigInteger beginAddress; | |
private final String endAddressStr; | |
private final BigInteger endAddress; | |
private final long sizeBytes; | |
private final String permissions; | |
private final long offset; | |
private final String device; | |
private final long inode; | |
private final String pathname; | |
private final Map<String, Long> attributes; | |
private final String vmFlags; | |
public ProcSMapItem(String beginAddress, String endAddress, String permissions, long offset, String device, long inode, String pathname, Map<String, Long> attributes, String vmFlags) { | |
this.beginAddressStr = beginAddress; | |
this.beginAddress = new BigInteger(beginAddress, 16); | |
this.endAddressStr = endAddress; | |
this.endAddress = new BigInteger(endAddress, 16); | |
this.sizeBytes = this.endAddress.subtract(this.beginAddress).longValue(); | |
this.permissions = permissions; | |
this.offset = offset; | |
this.device = device; | |
this.inode = inode; | |
this.pathname = pathname; | |
this.attributes = attributes; | |
this.vmFlags = vmFlags; | |
} | |
public BigInteger getBeginAddress() { | |
return beginAddress; | |
} | |
public BigInteger getEndAddress() { | |
return endAddress; | |
} | |
public long getInode() { | |
return inode; | |
} | |
public long getOffset() { | |
return offset; | |
} | |
public long getSizeBytes() { | |
return sizeBytes; | |
} | |
public String getPermissions() { | |
return permissions; | |
} | |
public String getDevice() { | |
return device; | |
} | |
public String getPathname() { | |
return pathname; | |
} | |
public String getBeginAddressStr() { | |
return beginAddressStr; | |
} | |
public String getEndAddressStr() { | |
return endAddressStr; | |
} | |
public Map<String, Long> getAttributes() { | |
return attributes; | |
} | |
public String getVmFlags() { | |
return vmFlags; | |
} | |
@Override | |
public String toString() { | |
return "ProcMapItem{" + | |
"beginAddressStr='" + beginAddressStr + '\'' + | |
", beginAddress=" + beginAddress + | |
", endAddressStr='" + endAddressStr + '\'' + | |
", endAddress=" + endAddress + | |
", sizeBytes=" + sizeBytes + | |
", attributes='" + permissions + '\'' + | |
", offset=" + offset + | |
", device='" + device + '\'' + | |
", inode=" + inode + | |
", pathname='" + pathname + '\'' + | |
'}'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.math.BigInteger; | |
import java.util.Map; | |
public class ProcSMapsParser { | |
public static SProcMap parse(InputStream procMapStream) throws IOException { | |
List<ProcSMapItem> items = new ArrayList<>(); | |
try (BufferedReader reader = new BufferedReader(new InputStreamReader(procMapStream));) { | |
String line; | |
StringBuilder buffer = new StringBuilder(); | |
while ((line = reader.readLine()) != null) { | |
buffer.setLength(0); | |
char[] chars = line.toCharArray(); | |
int i = 0; | |
// parse begin address | |
while (chars[i] != '-') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
String beginAddress = buffer.toString(); | |
buffer.setLength(0); | |
i++; | |
// parse end address | |
while (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
String endAddress = buffer.toString(); | |
buffer.setLength(0); | |
i++; | |
// parse permissions | |
while (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
String permissions = buffer.toString(); | |
buffer.setLength(0); | |
i++; | |
// | |
// parse offset | |
while (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
long offset = Long.decode("0x" + buffer.toString()); | |
buffer.setLength(0); | |
i++; | |
// parse device | |
while (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
String device = buffer.toString(); | |
buffer.setLength(0); | |
i++; | |
// parse end inode | |
while (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
i++; | |
} | |
long inode = Long.decode(buffer.toString()); | |
buffer.setLength(0); | |
i++; | |
// parse pathname | |
while (i < chars.length) { | |
if (chars[i] != ' ') { | |
buffer.append(chars[i]); | |
} | |
i++; | |
} | |
String pathName = buffer.toString(); | |
Map<String, Long> attributes = new HashMap<>(); | |
String vmFlags = ""; | |
while (true) { | |
buffer.setLength(0); | |
String attributeLine = reader.readLine(); | |
char[] attributedChars = attributeLine.toCharArray(); | |
int j = 0; | |
while (attributedChars[j] != ':') { | |
buffer.append(attributedChars[j]); | |
j++; | |
} | |
String attributeName = buffer.toString(); | |
j++; | |
buffer.setLength(0); | |
if (!attributeName.equals("VmFlags")) { | |
while (attributedChars[j] == ' ') { | |
j++; | |
} | |
while (j < attributedChars.length && attributedChars[j] != ' ') { | |
buffer.append(attributedChars[j]); | |
j++; | |
} | |
long attributeValue = Long.parseLong(buffer.toString()); | |
attributes.put(attributeName, attributeValue); | |
} else { | |
while (j < attributedChars.length) { | |
buffer.append(attributedChars[j]); | |
j++; | |
} | |
vmFlags = buffer.toString(); | |
break; | |
} | |
} | |
ProcSMapItem procMapItem = new ProcSMapItem(beginAddress, endAddress, permissions, offset, device, inode, pathName, attributes, vmFlags); | |
items.add(procMapItem); | |
} | |
} | |
return new SProcMap(items); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mport java.util.List; | |
public class SProcMap { | |
private final List<ProcSMapItem> items; | |
public SProcMap(List<ProcSMapItem> items) { | |
this.items = items; | |
} | |
public List<ProcSMapItem> getItems() { | |
return items; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment