2012-10-11 12 views
5

Tôi muốn tạo một chuỗi theo dõi việc sử dụng bộ nhớ và cách sử dụng CPU.Tạo một kết xuất chuỗi Java mà không cần khởi động lại.

Nếu ứng dụng đạt đến mức cao, tôi muốn tạo một bãi chứa đống hoặc kết xuất chuỗi.

Có cách nào để tạo thời gian chạy kết xuất chuỗi không cần khởi động lại không?

+0

Thread.getAllStackTraces() sẽ cung cấp cho bạn hầu hết những gì bạn muốn. Hoặc bạn có thể chạy 'jstack {pid}' như một chương trình bên ngoài. –

+2

Tôi không thể nghĩ ra một cách để tạo ra một kết xuất chuỗi yêu cầu khởi động lại ....;) –

+0

Thread.dumpStack() sẽ cho bạn dấu vết ngăn xếp cho chuỗi hiện tại. –

Trả lời

10

Đây là cách chúng tôi làm điều đó cách lập trình: http://pastebin.com/uS5jYpd4

Chúng tôi sử dụng JMXThreadMXBeanThreadInfo lớp:

ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); 
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0); 
... 

Bạn cũng có thể làm một kill -QUIT pid dưới ~ unix để đổ đống với tiêu chuẩn cấp tốc . Ngoài ra còn có jstack để đổ ngăn xếp của một JVM.

Chúng tôi cũng có một tự động hóa mà bãi stack nếu tỷ lệ trung bình tải của ứng dụng là trên một số ngưỡng:

private long lastCpuTimeMillis; 
private long lastPollTimeMillis; 

public void checkLoadAverage() { 
    long now = System.currentTimeMillis(); 
    long currentCpuMillis = getTotalCpuTimeMillis(); 
    double loadAvg = calcLoadAveragePercentage(now, currentCpuMillis); 
    if (loadAvg > LOAD_AVERAGE_DUMP_THRESHOLD) { 
     try { 
      dumpStack("Load average percentage is " + loadAvg); 
     } catch (IOException e) { 
      // Oh well, we tried 
     } 
    } 
    lastCpuTimeMillis = currentCpuMillis; 
    lastPollTimeMillis = now; 
} 

private long getTotalCpuTimeMillis() { 
    long total = 0; 
    for (long id : threadMxBean.getAllThreadIds()) { 
     long cpuTime = threadMxBean.getThreadCpuTime(id); 
     if (cpuTime > 0) { 
      total += cpuTime; 
     } 
    } 
    // since is in nano-seconds 
    long currentCpuMillis = total/1000000; 
    return currentCpuMillis; 
} 

private double calcLoadAveragePercentage(long now, long currentCpuMillis) { 
    long timeDiff = now - lastPollTimeMillis; 
    if (timeDiff == 0) { 
     timeDiff = 1; 
    } 
    long cpuDiff = currentCpuMillis - lastCpuTimeMillis; 
    double loadAvg = (double) cpuDiff/(double) timeDiff; 
    return loadAvg; 
} 
+0

Cảm ơn rất nhiều vì giải pháp !! –

0

Có, bạn có thể tạo vùng lưu trữ ngăn xếp của riêng mình bằng MXBeans được quản lý tích hợp. Cụ thể, bạn có thể lấy tất cả ThreadInfos hiện tại từ ThreadMXBean và ghi nội dung đến vị trí mong muốn của bạn.

7

Để đổ chủ đề với tiêu chuẩn ra, bạn có thể làm điều gì đó như thế này

ThreadInfo[] threads = ManagementFactory.getThreadMXBean() 
     .dumpAllThreads(true, true); 
for(final ThreadInfo info : threads) 
    System.out.print(info); 

trong Java 6 cách sử dụng các lớp ThreadMXBean. Nhưng tôi sẽ đề nghị sử dụng ghi thực sự thay vì đầu ra tiêu chuẩn.

2

Hãy thử “giết -QUIT” PROCESS_ID ví dụ

kill -QUIT 2134 

này sẽ kích hoạt kết xuất chuỗi mà không cần khởi động lại nó

+0

Chắc chắn là đặc điểm nổi bật nhất. Và nếu bạn chỉ có một tiến trình java, 'kill -QUIT' pidof java'' sẽ thực hiện thủ thuật. – pdeschen