2011-01-21 60 views
32

Tôi đang kiểm tra một quá trình Java trong Linux sử dụngKiểm tra Java đề trong Linux sử dụng đầu

top -H 

Tuy nhiên, tôi không thể đọc được tên của thread trong cột "COMMAND" (vì nó quá dài). Nếu tôi sử dụng 'c' để mở rộng tên đầy đủ của quá trình, sau đó nó vẫn còn dài để phù hợp.

Tôi làm cách nào để có được tên đầy đủ của lệnh?

+0

sẽ đầu cung cấp cho chủ đề java thông tin ?? –

+0

Đó không phải là chủ đề mà là quá trình. – OscarRyz

+1

@OscarRyz, -H cho biết đầu đề danh sách (bản địa). –

Trả lời

23

Bạn có thể kiểm tra các chuỗi java bằng công cụ jstack. Nó sẽ liệt kê các tên, stacktraces và các thông tin hữu ích khác của tất cả các luồng thuộc về quy trình pid quy định.

Chỉnh sửa: Tham số nid trong kết xuất chuỗi của jstack là phiên bản hex của LWP được hiển thị bằng đầu trong cột pid cho chủ đề.

+0

Tôi nghĩ rằng OP có nghĩa là quá trình và không thread – OscarRyz

+2

Tôi nghĩ rằng ông có nghĩa là chính xác những gì ông đã viết. Ông thậm chí còn sử dụng -H như tham số cho "top" để nói "top" để hiển thị chủ đề. –

0

Việc tăng biến môi trường COLUMNS có cung cấp cho bạn thêm thông tin trong màn hình không?

+0

Tôi không nghĩ như vậy ... có dư thừa phòng trên thiết bị đầu cuối, nhưng cột COMMAND chỉ là quá hẹp. – Jake

+0

Để tôi thay đổi kích thước thiết bị đầu cuối Gnome (có thể đặt COLUMNS) sẽ làm, nhưng tôi cần một cái gì đó giống như thiết bị đầu cuối 100 '' để đến phần liên quan của dòng lệnh. – maaartinus

3

Chủ đề không có tên liên quan đến hạt nhân; họ chỉ có số ID. JVM gán tên cho các luồng, nhưng đó là dữ liệu nội bộ riêng tư trong tiến trình, mà chương trình "trên cùng" không thể truy cập (và cũng không biết về nó).

21

Đây có thể là một chút cũ, nhưng đây là những gì tôi đã làm để kết hợp đầu và jstack với nhau. Tôi đã sử dụng hai kịch bản, nhưng tôi chắc chắn rằng tất cả có thể được thực hiện trong một.

Trước tiên, tôi lưu đầu ra của đầu với PID cho chủ đề java của tôi vào một tập tin và lưu đầu ra jstack vào tập tin khác:

#!/bin/sh 
top -H -b -n 1 | grep java > /tmp/top.log 
jstack -l `ps fax | grep java | grep tomcat | sed "s/ *\([0-9]*\) .*/\1/g"` > /tmp/jstack.log 

Sau đó, tôi sử dụng một kịch bản perl để gọi các tập lệnh bash (gọi cpu-java.sh đây) và kinda hợp nhất hai tập tin (/tmp/top.log và /tmp/jstack.log):

#!/usr/bin/perl 
system("sh cpu-java.sh"); 
open LOG, "/tmp/top.log" or die $!; 
print "PID\tCPU\tMem\tJStack Info\n"; 
while ($l = <LOG>) { 
    $pid = $l; 
    $pid =~ s/root.*//g; 
    $pid =~ s/ *//g; 
    $hex_pid = sprintf("%#x", $pid); 
    @values = split(/\s{2,}/, $l); 
    $pct = $values[4]; 
    $mem = $values[5]; 
    open JSTACK, "/tmp/jstack.log" or die $!; 
    while ($j = <JSTACK>){ 
     if ($j =~ /.*nid=.*/){ 
      if ($j =~ /.*$hex_pid.*/){ 
       $j =~ s/\n//; 
       $pid =~ s/\n//; 
       print $pid . "\t" . $pct . "\t" . $mem . "\t" . $j . "\n"; 
      } 
     } 
    } 
    close JSTACK; 
} 
close LOG; 

sản lượng giúp tôi để tìm ra các chủ đề được hogging cpu của tôi :

PID  CPU Mem JStack Info 
22460 0 8.0 "main" prio=10 tid=0x083cb800 nid=0x57bc runnable [0xb6acc000] 
22461 0 8.0 "GC task thread#0 (ParallelGC)" prio=10 tid=0x083d2c00 nid=0x57bd runnable 
22462 0 8.0 "GC task thread#1 (ParallelGC)" prio=10 tid=0x083d4000 nid=0x57be runnable 
22463 0 8.0 "GC task thread#2 (ParallelGC)" prio=10 tid=0x083d5800 nid=0x57bf runnable 
22464 0 8.0 "GC task thread#3 (ParallelGC)" prio=10 tid=0x083d7000 nid=0x57c0 runnable 
... 

Sau đó, tôi có thể quay lại /tmp/jstack.log và xem xét dấu vết ngăn xếp cho chuỗi có vấn đề và cố gắng tìm ra những gì đang diễn ra từ đó. Tất nhiên giải pháp này phụ thuộc vào nền tảng, nhưng nó sẽ làm việc với hầu hết các hương vị của * nix và một số tinh chỉnh ở đây và ở đó.

+0

vẫn là một câu trả lời rất hữu ích, cảm ơn @Andre! – Gregor

11

Tôi đã tạo ra một lệnh giống như trên cùng cụ thể để hình dung các chuỗi Java được sắp xếp theo mức sử dụng CPU và đăng mã nguồn tại: https://github.com/jasta/jprocps. Cú pháp dòng lệnh là gần như không giàu như trên, nhưng nó hỗ trợ một số các lệnh tương tự:

 
jtop -n 1 

Mẫu đầu ra (hiển thị kiến ​​và IntelliJ chạy):

 
    PID TID USER  %CPU %MEM THREAD 
13480 13483 jasta  104 2.3 main 
13480 13497 jasta  86.3 2.3 C2 CompilerThread1 
13480 13496 jasta  83.0 2.3 C2 CompilerThread0 
4866 4953 jasta  1.0 13.4 AWT-EventQueue-1 12.1.4#IC-129.713, eap:false 
4866 14154 jasta  0.9 13.4 ApplicationImpl pooled thread 36 
4866 5219 jasta  0.8 13.4 JobScheduler pool 5/8 

Từ đầu ra này , Tôi có thể kéo dấu vết ngăn xếp của luồng trong jconsole hoặc jstack theo cách thủ công và tìm hiểu điều gì đang diễn ra.

+0

Freakin tuyệt vời. :) –

+1

đã thử nó nhưng tôi nhận được KeyError: 'tid' – MitchBroadhead

+0

Tôi nhận được ... "từ argparse nhập khẩu ArgumentParser ImportError: Không có mô-đun tên argparse" – Amalgovinus

2

Với OpenJDK trên Linux, JavaThread tên không được truyền tới native threads, bạn không thể thấy tên chuỗi java trong khi kiểm tra các chuỗi gốc bằng bất kỳ công cụ nào.

Tuy nhiên có một số công việc cơ bản dở dang:

Cá nhân, tôi tìm thấy những công cụ phát triển OpenJDK chậm vì vậy tôi chỉ cần áp dụng các bản vá lỗi bản thân mình.

0

Câu hỏi cũ, nhưng tôi chỉ gặp vấn đề tương tự với top.

Hóa ra, bạn có thể ra cuộn hàng đầu sang bên phải chỉ đơn giản bằng cách sử dụng các phím con trỏ :)

(nhưng tiếc là sẽ không có bất kỳ chủ đề tên hiển thị)

1

Như xa như tôi phát hiện ra jstack is outdated như của JDK 8. Những gì tôi sử dụng để lấy tất cả các tên Java chủ đề là:

<JDK_HOME>/bin/jcmd <PID> Thread.print 

Kiểm tra jcmd documentation để biết thêm.

1

Tập lệnh trình bao này kết hợp đầu ra từ jstack và trên cùng để liệt kê các chuỗi Java bằng cách sử dụng CPU. Nó mong đợi một đối số, người dùng tài khoản sở hữu các quy trình.

Tên: jstack-top.sh

#!/bin/sh 
# 
# jstack-top - join jstack and top to show cpu usage, etc. 
# 
# Usage: jstack-top <user> | view - 
# 

USER=$1 
TOPS="/tmp/jstack-top-1.log" 
JSKS="/tmp/jstack-top-2.log" 

PIDS="$(ps -u ${USER} --no-headers -o pid:1,cmd:1 | grep 'bin/java' | grep -v 'grep' | cut -d' ' -f1)" 
if [ -f ${JSKS} ]; then 
    rm ${JSKS} 
fi 
for PID in ${PIDS}; do 
    jstack -l ${PID} | grep "nid=" >>${JSKS} 
done 

top -u ${USER} -H -b -n 1 | grep "%CPU\|java" | sed -e 's/[[:space:]]*$//' > ${TOPS} 
while IFS= read -r TOP; do 
    NID=$(echo "${TOP}" | sed -e 's/^[[:space:]]*//' | cut -d' ' -f1) 
    if [ "${NID}" = "PID" ]; then 
     JSK="" 
     TOP="${TOP} JSTACK" 
    else 
     NID=$(printf 'nid=0x%x' ${NID}) 
     JSK=$(grep "${NID} " ${JSKS}) 
    fi 
    echo "${TOP} ${JSK}" 
done < "${TOPS}" 
Các vấn đề liên quan