All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.polaris.core.os.JShells Maven / Gradle / Ivy

There is a newer version: 3.2.1
Show newest version
package io.polaris.core.os;

import io.polaris.core.regex.Patterns;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Qt
 * @since 1.8
 */
public class JShells {

	public static List getJMapHistoInfo() {
		return getJMapHistoInfo(128);
	}

	public static List getJMapHistoInfo(int maxSize) {
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(new String[]{"jmap", "-histo", String.valueOf(OS.getPid())});
			InputStream stdin = process.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(stdin, StandardCharsets.UTF_8));
			/*
			 num     #instances         #bytes  class name
			----------------------------------------------
			   1:        288111       40311136  [C
			   2:         29244       15318128  [B
			   3:        197913        4749912  java.lang.String
			   ...
			  1618:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
			  Total        969047       81279648
			 */
			List list = new ArrayList<>(Math.min(Math.max(128, maxSize), 16384));
			int size = 0;
			for (String line = br.readLine(); line != null; line = br.readLine()) {
				line = line.trim();
				if (size >= maxSize) {
					continue;
				}
				Pattern pattern = Patterns.getPattern("(\\d+):\\s+(\\d+)\\s+(\\d+)\\s+([^\\s]+)");
				Matcher matcher = pattern.matcher(line);
				if (matcher.find()) {
					JMapHistoInfo info = new JMapHistoInfo();
					info.setNum(Integer.parseInt(matcher.group(1)));
					info.setInstances(Integer.parseInt(matcher.group(2)));
					info.setBytes(Long.parseLong(matcher.group(3)));
					info.setClassName((matcher.group(4)));
					list.add(info);
					size++;
				}
			}
			process.waitFor();
			return list;
		} catch (Exception ignore) {
			return Collections.emptyList();
		} finally {
			if (process != null) {
				try {
					process.destroy();
				} catch (Exception ignore) {
				}
			}
		}
	}

	public static List getJStackInfo() {
		Process process = null;
		try {
			process = Runtime.getRuntime().exec(new String[]{"jstack", "-l", String.valueOf(OS.getPid())});
			InputStream stdin = process.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(stdin, StandardCharsets.UTF_8));

			List stackThreadInfoList = new ArrayList<>(128);
			StringBuilder traceHeadBuilder = new StringBuilder();
			StringBuilder traceBodyBuilder = new StringBuilder();
			boolean inTraceBody = false;
			JStackThreadInfo stackThreadInfo = null;
			for (String line = br.readLine(); line != null; line = br.readLine()) {
				line = line.trim();
				Pattern pattern = Patterns.getPattern("\"(.+)\"(?:\\s*#(\\d+))(?:\\s*(daemon))?(?:\\s*prio=(\\d+))(?:\\s*os_prio=(\\d+))(?:\\s*tid=([\\w]+))(?:\\s*nid=([\\w]+))");
				Matcher matcher = pattern.matcher(line);
				if (matcher.find()) {
					if (stackThreadInfo != null) {
						stackThreadInfo.setStackTrace(traceBodyBuilder.toString());
						stackThreadInfo.setStackTraceHeader(traceHeadBuilder.toString());
					}
					stackThreadInfoList.add(stackThreadInfo = new JStackThreadInfo());
					inTraceBody = false;
					traceHeadBuilder.setLength(0);
					traceBodyBuilder.setLength(0);

					String threadName = matcher.group(1);
					stackThreadInfo.setThreadName(threadName);
					String threadId = matcher.group(2);
					if (threadId != null && threadId.length() > 0) {
						stackThreadInfo.setThreadId(Long.parseLong(threadId));
					}
					String daemon = matcher.group(3);
					if (daemon != null && daemon.length() > 0) {
						stackThreadInfo.setDaemon(true);
					}
					String prio = matcher.group(4);
					if (prio != null && prio.length() > 0) {
						stackThreadInfo.setPriority(Integer.parseInt(prio));
					}
					String osPrio = matcher.group(5);
					if (osPrio != null && osPrio.length() > 0) {
						stackThreadInfo.setOsPriority(Integer.parseInt(osPrio));
					}
					String tid = matcher.group(6);
					if (tid != null && tid.length() > 0) {
						stackThreadInfo.setTid(tid);
					}
					String nid = matcher.group(7);
					if (nid != null && nid.length() > 0) {
						stackThreadInfo.setNid(nid);
						stackThreadInfo.setPid(Integer.parseInt(nid.replace("0x", ""), 16));
					}

				} else if (line.startsWith("at")) {
					inTraceBody = true;
				}
				if (stackThreadInfo != null) {
					if (inTraceBody) {
						traceBodyBuilder.append(line).append("\n");
					} else {
						traceHeadBuilder.append(line).append("\n");
					}
				}
			}
			if (stackThreadInfo != null) {
				stackThreadInfo.setStackTrace(traceBodyBuilder.toString());
				stackThreadInfo.setStackTraceHeader(traceHeadBuilder.toString());
			}
			process.waitFor();
			return stackThreadInfoList;
		} catch (Exception ignore) {
			return Collections.emptyList();
		} finally {
			if (process != null) {
				try {
					process.destroy();
				} catch (Exception ignore) {
				}
			}
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy