ฉันต้องการตรวจสอบการใช้งาน CPU และหน่วยความจำสำหรับเซิร์ฟเวอร์ใน java มีใครรู้บ้างว่ามันทำได้อย่างไร?
ฉันต้องการตรวจสอบการใช้งาน CPU และหน่วยความจำสำหรับเซิร์ฟเวอร์ใน java มีใครรู้บ้างว่ามันทำได้อย่างไร?
คำตอบ:
หากคุณกำลังมองหาหน่วยความจำโดยเฉพาะใน JVM:
Runtime runtime = Runtime.getRuntime();
NumberFormat format = NumberFormat.getInstance();
StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
sb.append("free memory: " + format.format(freeMemory / 1024) + "<br/>");
sb.append("allocated memory: " + format.format(allocatedMemory / 1024) + "<br/>");
sb.append("max memory: " + format.format(maxMemory / 1024) + "<br/>");
sb.append("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) + "<br/>");
อย่างไรก็ตามควรนำมาเป็นค่าประมาณเท่านั้น ...
package mkd.Utils;
import java.io.File;
import java.text.NumberFormat;
public class systemInfo {
private Runtime runtime = Runtime.getRuntime();
public String Info() {
StringBuilder sb = new StringBuilder();
sb.append(this.OsInfo());
sb.append(this.MemInfo());
sb.append(this.DiskInfo());
return sb.toString();
}
public String OSname() {
return System.getProperty("os.name");
}
public String OSversion() {
return System.getProperty("os.version");
}
public String OsArch() {
return System.getProperty("os.arch");
}
public long totalMem() {
return Runtime.getRuntime().totalMemory();
}
public long usedMem() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
public String MemInfo() {
NumberFormat format = NumberFormat.getInstance();
StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
sb.append("Free memory: ");
sb.append(format.format(freeMemory / 1024));
sb.append("<br/>");
sb.append("Allocated memory: ");
sb.append(format.format(allocatedMemory / 1024));
sb.append("<br/>");
sb.append("Max memory: ");
sb.append(format.format(maxMemory / 1024));
sb.append("<br/>");
sb.append("Total free memory: ");
sb.append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
sb.append("<br/>");
return sb.toString();
}
public String OsInfo() {
StringBuilder sb = new StringBuilder();
sb.append("OS: ");
sb.append(this.OSname());
sb.append("<br/>");
sb.append("Version: ");
sb.append(this.OSversion());
sb.append("<br/>");
sb.append(": ");
sb.append(this.OsArch());
sb.append("<br/>");
sb.append("Available processors (cores): ");
sb.append(runtime.availableProcessors());
sb.append("<br/>");
return sb.toString();
}
public String DiskInfo() {
/* Get a list of all filesystem roots on this system */
File[] roots = File.listRoots();
StringBuilder sb = new StringBuilder();
/* For each filesystem root, print some info */
for (File root : roots) {
sb.append("File system root: ");
sb.append(root.getAbsolutePath());
sb.append("<br/>");
sb.append("Total space (bytes): ");
sb.append(root.getTotalSpace());
sb.append("<br/>");
sb.append("Free space (bytes): ");
sb.append(root.getFreeSpace());
sb.append("<br/>");
sb.append("Usable space (bytes): ");
sb.append(root.getUsableSpace());
sb.append("<br/>");
}
return sb.toString();
}
}
freeMemory
ที่นี่ส่งคืนจำนวนหน่วยความจำที่มีอยู่ใน JVM ซึ่งแตกต่างกันมาก
หากคุณกำลังใช้ Sun JVM และสนใจการใช้งานหน่วยความจำภายในของแอปพลิเคชัน (จำนวนหน่วยความจำที่แอปของคุณใช้อยู่) ฉันต้องการเปิดการบันทึกการรวบรวมขยะในตัวของ JVM คุณเพียงแค่เพิ่ม -verbose: gc ในคำสั่งเริ่มต้น
จากเอกสาร The Sun:
อาร์กิวเมนต์บรรทัดคำสั่ง -verbose: gc พิมพ์ข้อมูลในทุกคอลเลกชัน โปรดทราบว่ารูปแบบของเอาต์พุต -verbose: gc อาจเปลี่ยนแปลงได้ระหว่างรีลีสของแพลตฟอร์ม J2SE ตัวอย่างเช่นนี่คือผลลัพธ์จากแอ็พพลิเคชันเซิร์ฟเวอร์ขนาดใหญ่:
[GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs]
ที่นี่เราจะเห็นคอลเล็กชันย่อยสองคอลเลคชันและหนึ่งคอลเล็กชันหลัก ตัวเลขก่อนและหลังลูกศร
325407K->83000K (in the first line)
ระบุขนาดรวมของวัตถุที่มีชีวิตก่อนและหลังการเก็บขยะตามลำดับ หลังจากการรวบรวมเล็กน้อยการนับรวมถึงวัตถุที่ไม่จำเป็นต้องมีชีวิต แต่ไม่สามารถเรียกคืนได้ไม่ว่าจะเป็นเพราะพวกมันมีชีวิตโดยตรงหรือเป็นเพราะอยู่ภายในหรืออ้างอิงจากรุ่นที่ครอบครอง ตัวเลขในวงเล็บ
(776768K) (in the first line)
คือพื้นที่ว่างทั้งหมดโดยไม่นับพื้นที่ในการสร้างแบบถาวรซึ่งเป็นจำนวนฮีปทั้งหมดลบหนึ่งในช่องว่างของผู้รอดชีวิต การรวบรวมเล็กน้อยใช้เวลาประมาณหนึ่งในสี่ของวินาที
0.2300771 secs (in the first line)
ดูข้อมูลเพิ่มเติมได้ที่: http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
จากที่นี่
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
long prevUpTime = runtimeMXBean.getUptime();
long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
double cpuUsage;
try
{
Thread.sleep(500);
}
catch (Exception ignored) { }
operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long upTime = runtimeMXBean.getUptime();
long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
long elapsedCpu = processCpuTime - prevProcessCpuTime;
long elapsedTime = upTime - prevUpTime;
cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
System.out.println("Java CPU: " + cpuUsage);
operatingSystemMXBean.getProcessCpuLoad();
? ตามเอกสารของ Oracle วิธีนี้จะส่งคืน "ส่งคืน" การใช้งาน cpu ล่าสุด "สำหรับกระบวนการ Java Virtual Machine" แต่ฉันเห็นความแตกต่างระหว่างวิธีของคุณกับวิธีนี้ค่อนข้างมาก
OperatingSystemMXBean
คลาส หนึ่งคืออินเทอร์เฟซที่มีให้ในjava.lang
. com.sun.management
แต่ยังมีอีกรุ่นหนึ่งที่ขยายในเรื่องนี้ นั่นคือวิธีการที่ฉันอ้างถึงคือจากนั้นOperatingSystemMXBean
JMX, MXBeans (ThreadMXBean ฯลฯ ) ที่ให้มาจะให้การใช้งานหน่วยความจำและ CPU แก่คุณ
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();
สำหรับการใช้งานหน่วยความจำสิ่งต่อไปนี้จะใช้งานได้
long total = Runtime.getRuntime().totalMemory();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
สำหรับการใช้งาน CPU คุณจะต้องใช้แอปพลิเคชันภายนอกเพื่อวัดผล
เนื่องจาก Java 1.5 JDK มาพร้อมกับเครื่องมือใหม่: JConsole ซึ่งสามารถแสดงการใช้งาน CPU และหน่วยความจำของ JVM 1.5 หรือใหม่กว่าได้ มันสามารถทำแผนภูมิของพารามิเตอร์เหล่านี้ส่งออกเป็น CSV แสดงจำนวนคลาสที่โหลดจำนวนอินสแตนซ์การหยุดชะงักเธรด ฯลฯ ...
หากคุณใช้โซลูชัน runtime / totalMemory ที่มีการโพสต์ในคำตอบมากมายที่นี่ (ฉันทำมามากแล้ว) อย่าลืมบังคับให้รวบรวมขยะสองชุดก่อนหากคุณต้องการผลลัพธ์ที่ค่อนข้างแม่นยำ / สอดคล้องกัน
สำหรับประสิทธิภาพ Java มักจะอนุญาตให้ขยะเติมหน่วยความจำทั้งหมดก่อนที่จะบังคับให้ GC และถึงแม้จะไม่ใช่ GC ที่สมบูรณ์ดังนั้นผลลัพธ์ของคุณสำหรับ runtime.freeMemory () จะอยู่ที่ใดที่หนึ่งระหว่างจำนวนหน่วยความจำว่าง "จริง" กับ 0 เสมอ .
GC แรกไม่ได้รับทุกอย่าง แต่ได้รับประโยชน์สูงสุด
การแกว่งขึ้นก็คือถ้าคุณโทรไปที่ freeMemory () คุณจะได้หมายเลขที่ไร้ประโยชน์และแตกต่างกันไป แต่ถ้าทำ 2 gc ก่อนมันเป็นมาตรวัดที่น่าเชื่อถือมาก นอกจากนี้ยังทำให้กิจวัตรประจำวันช้าลงมาก (อาจเป็นวินาที)
วัตถุรันไทม์ของ Java สามารถรายงานการใช้หน่วยความจำของ JVM สำหรับการใช้ CPU คุณจะต้องใช้ยูทิลิตี้ภายนอกเช่น Unix's top หรือ Windows Process Manager
JConsoleเป็นวิธีง่ายๆในการตรวจสอบแอปพลิเคชัน Java ที่ทำงานอยู่หรือคุณสามารถใช้ Profiler เพื่อรับข้อมูลรายละเอียดเพิ่มเติมเกี่ยวกับแอปพลิเคชันของคุณ ฉันชอบใช้NetBeans Profilerสำหรับสิ่งนี้
นี่คือรหัสง่ายๆในการคำนวณการใช้หน่วยความจำปัจจุบันเป็นเมกะไบต์:
double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));
ฉันจะเพิ่มวิธีต่อไปนี้เพื่อติดตามการโหลด CPU:
import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
double getCpuLoad() {
OperatingSystemMXBean osBean =
(com.sun.management.OperatingSystemMXBean) ManagementFactory.
getPlatformMXBeans(OperatingSystemMXBean.class);
return osBean.getProcessCpuLoad();
}
คุณสามารถอ่านเพิ่มเติมได้ที่นี่
YourKit Java Profiler เป็นทางออกที่ดีในเชิงพาณิชย์ คุณสามารถค้นหาข้อมูลเพิ่มเติมในเอกสารบนโปรไฟล์ของ CPUและหน่วยความจำโปรไฟล์
หากคุณใช้ Tomcat โปรดดูPsi Probeซึ่งช่วยให้คุณสามารถตรวจสอบการใช้หน่วยความจำภายในและภายนอกรวมถึงพื้นที่อื่น ๆ
สำหรับ Eclipse คุณสามารถใช้ TPTP (Test and Performance Tools Platform) เพื่อวิเคราะห์การใช้หน่วยความจำและข้อมูลเพิ่มเติมอื่น ๆ