如何用Java获取任务管理器内存及MySQL、MongoDB、Neo4j实时内存?
Hey there! Let's tackle your memory monitoring needs step by step, since you're working on Windows with Eclipse. Below are practical, Java-based solutions for each of your requirements:
这里分两种常见场景:监控当前Java进程的内存,或者监控任意Windows进程(比如数据库进程)的内存。
1. 获取当前JVM进程的内存(对应任务管理器中Java进程的内存)
Java自带的Runtime类就能快速拿到核心内存数据,这是最直接的方式:
public class JvmMemoryMonitor { public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); // 转换为MB单位,方便阅读 long totalMemory = runtime.totalMemory() / (1024 * 1024); long freeMemory = runtime.freeMemory() / (1024 * 1024); long usedMemory = totalMemory - freeMemory; long maxMemory = runtime.maxMemory() / (1024 * 1024); System.out.println("JVM已分配总内存: " + totalMemory + " MB"); System.out.println("JVM当前已使用内存: " + usedMemory + " MB"); System.out.println("JVM空闲内存: " + freeMemory + " MB"); System.out.println("JVM最大可分配内存: " + maxMemory + " MB"); } }
2. 获取任意Windows进程的内存(比如MySQL/MongoDB进程)
如果要监控其他进程(比如mysqld.exe或mongod.exe)的内存,有两种可靠方式:
方式1:执行Windowstasklist命令解析输出
通过调用系统命令并解析CSV格式的结果,无需额外依赖:
import java.io.BufferedReader; import java.io.InputStreamReader; public class WindowsProcessMonitor { public static void main(String[] args) { try { // 替换为你要监控的进程名,比如mongod.exe Process process = Runtime.getRuntime().exec("tasklist /fi \"IMAGENAME eq mysqld.exe\" /fo CSV /nh"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { // 解析CSV格式:"mysqld.exe","1234","Console","1","1,234 K" String[] parts = line.split("\",\""); if (parts.length >= 5) { String processName = parts[0].replace("\"", ""); String pid = parts[1]; String memoryUsage = parts[4].replace("\"", "").replace(",", ""); System.out.println("进程名: " + processName); System.out.println("PID: " + pid); System.out.println("内存使用: " + memoryUsage + " KB"); } } reader.close(); } catch (Exception e) { e.printStackTrace(); } } }
方式2:用JNA调用Windows API(更精准)
这种方式能直接获取系统底层的内存数据,需要引入JNA依赖(在Eclipse里可手动添加jna.jar和jna-platform.jar):
import com.sun.jna.Native; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Psapi; import com.sun.jna.platform.win32.WinNT; public class WindowsProcessMemoryAPI { public static void main(String[] args) { // 替换为目标进程的PID(可从tasklist或任务管理器获取) int pid = 1234; WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess( Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ, false, pid ); if (processHandle != null) { Psapi.PROCESS_MEMORY_COUNTERS_EX pmc = new Psapi.PROCESS_MEMORY_COUNTERS_EX(); if (Psapi.INSTANCE.GetProcessMemoryInfo(processHandle, pmc, pmc.size())) { // 对应任务管理器的"专用工作集" long privateBytes = pmc.PrivateUsage / (1024 * 1024); // 对应任务管理器的"内存"列 long workingSetSize = pmc.WorkingSetSize / (1024 * 1024); System.out.println("进程专用工作集: " + privateBytes + " MB"); System.out.println("进程工作集内存: " + workingSetSize + " MB"); } Kernel32.INSTANCE.CloseHandle(processHandle); } } }
通过JDBC执行MySQL的系统查询语句,可获取数据库层面的内存使用细节(比如InnoDB缓冲池、连接池内存等)。
首先确保项目引入MySQL JDBC驱动(比如mysql-connector-java),然后使用以下代码:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class MySQLMemoryMonitor { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/?useSSL=false&serverTimezone=UTC"; String user = "root"; String password = "your_mysql_password"; try (Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement()) { // 查询InnoDB缓冲池内存状态 String innodbQuery = "SHOW GLOBAL STATUS LIKE 'InnoDB_buffer_pool%'"; ResultSet rs = stmt.executeQuery(innodbQuery); while (rs.next()) { System.out.println(rs.getString(1) + ": " + rs.getString(2)); } rs.close(); // 查询全局内存配置 String globalMemQuery = "SHOW GLOBAL VARIABLES LIKE '%buffer%'"; rs = stmt.executeQuery(globalMemQuery); while (rs.next()) { System.out.println(rs.getString(1) + ": " + rs.getString(2)); } rs.close(); } catch (Exception e) { e.printStackTrace(); } } }
注意:你的MySQL账号需要拥有PROCESS权限才能查询这些系统状态。
使用MongoDB Java Driver调用serverStatus命令,可获取服务器的内存使用详情(包括存储引擎缓存)。
首先引入MongoDB驱动(比如mongodb-driver-sync),然后使用以下代码:
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; import org.bson.Document; public class MongoDBMemoryMonitor { public static void main(String[] args) { // 替换为你的MongoDB连接字符串 try (MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoDatabase adminDb = mongoClient.getDatabase("admin"); Document serverStatus = adminDb.runCommand(new Document("serverStatus", 1)); // 提取基础内存信息 Document mem = serverStatus.get("mem", Document.class); long residentMem = mem.getLong("resident"); long virtualMem = mem.getLong("virtual"); long mappedMem = mem.getLong("mapped"); System.out.println("MongoDB驻留内存: " + residentMem + " MB"); System.out.println("MongoDB虚拟内存: " + virtualMem + " MB"); System.out.println("MongoDB映射内存: " + mappedMem + " MB"); // 提取WiredTiger存储引擎缓存使用 Document wiredTiger = serverStatus.get("wiredTiger", Document.class); Document cache = wiredTiger.get("cache", Document.class); long cacheUsed = cache.getLong("bytes currently in the cache") / (1024 * 1024); System.out.println("WiredTiger缓存已使用: " + cacheUsed + " MB"); } catch (Exception e) { e.printStackTrace(); } } }
通过Neo4j Java Driver执行Cypher查询或JMX命令,可获取数据库的内存配置和实时使用情况。
首先引入Neo4j驱动(比如neo4j-java-driver),然后使用以下代码:
import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Result; import org.neo4j.driver.Session; public class Neo4jMemoryMonitor { public static void main(String[] args) { String uri = "bolt://localhost:7687"; String user = "neo4j"; String password = "your_neo4j_password"; try (Driver driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password)); Session session = driver.session()) { // 查询内存配置参数 Result configResult = session.run("CALL dbms.listConfig() YIELD name, value WHERE name STARTS WITH 'dbms.memory' RETURN name, value"); while (configResult.hasNext()) { var record = configResult.next(); System.out.println(record.get("name").asString() + ": " + record.get("value").asString()); } // 通过JMX查询实时内存池使用 Result jmxResult = session.run("CALL dbms.queryJmx('org.neo4j:*') YIELD name, attributes WHERE name CONTAINS 'MemoryPool' RETURN name, attributes"); while (jmxResult.hasNext()) { var record = jmxResult.next(); String poolName = record.get("name").asString(); var attrs = record.get("attributes").asMap(); System.out.println("\n内存池: " + poolName); System.out.println("已使用内存: " + attrs.get("Usage").get("used") + " bytes"); System.out.println("最大内存: " + attrs.get("Usage").get("max") + " bytes"); } } catch (Exception e) { e.printStackTrace(); } } }
注意:默认的neo4j账号具备执行这些系统命令的权限,如果使用自定义账号,需要确保权限足够。
内容的提问来源于stack exchange,提问作者Rodrigo

