<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    細心!用心!耐心!

    吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

    BlogJava 聯系 聚合 管理
      1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
    之前看過一篇很不錯文檔(WLS的異常高CPU占用率分析診斷),原作英文版的,有幸看到,遺憾的是沒保存,不過中文版翻譯的也不錯,在之前的dev2dev和OTN上都有那篇文檔的中文版。

    原文對5種常見的操作系統下WLS的異常高CPU占用率分析都有,SUN-Solaris、HP-UX、IBM-AIX、MS-Windows上的都比較詳細,唯獨沒看明白Linux平臺上的分析,而且現在看來,那篇文章中關于查找占用CPU過高的內核進程號的地方一筆帶過,周六、周末在家又認真的看了看Linux平臺下的top和ps這兩個常用命令的幫助,最終得已清晰,這里又加以補充,并作文檔一篇跟大家共享,歡迎賜教。

    一、進程、線程和輕量級進程(Lightweight,簡稱LWP)簡述

    進程是資源管理的最小單位,而線程又是程序執行的最小單位,一個進程至少需要一個線程作為它的指令執行體,進程管理著資源(比如CPU時間片、虛擬內存、文件句柄、信號處理器等),線程可以共享這些資源。輕量級進程(LWP)是一種由內核支持的用戶線程。


    每一個進程有一個或多個LWP,而每個LWP都與一個特定的內核線程關聯(這種線程模型就是LinuxThreads和NPTL(符合POSIX)共同所有的1:1[一對一]的模型),不過NPTL線程模型中,進程和線程的對應關系有點復雜(還有1:n,n:n的對應關系)。
    關于LWP與內核線程的1:1的映射關系,下面從現代的Solaris
    OS(使用了NPTL線程模型)中截取的一段映射的實例來理解:


    -----------------lwp#
    1 / thread# 1--------------------


    d22faaf5
    lwp_cond_wait (8074d00, 8074ce8, 0, 0)


    d1da51fc
    __1cCosHSolarisFEventEdown6M_v_ (8074ce8) + 58


    ………………………………


    -----------------lwp#
    2 / thread# 2--------------------


    d22faaf5
    lwp_cond_wait (8073c00, 8073be8, cf4dee68, 0)


    ………………………………


    -----------------
    lwp# 26 / thread# 26 --------------------


    d1a4814c
    ???????? ()


    -----------------lwp#
    27 / thread# 27--------------------


    ………………………………

    二、RedHat
    Linux中的LWP和pthread號的查看



    由于當前IT行業中,Linux版本較多,而且HotSpot和JRockit認證支持的Linux供應商不同版本的Linux,所使用的線程模型、版本也各不一樣,所以這里只討論RedHat
    Linux, 紅帽公司從RedHat Linux 9(Linux kernel 2.4.20[glibc 2.3])版本開始采用POSIX
    0.6線程模型。隨后的Linux發行版中慢慢的都拋棄了LinuxThreads線程模型,轉向支持基于POSIX線程(POSIX threads,又稱
    pthreads)的NPTL(Native POSIX Threads Library for
    Linux)的新型線程模型(IBM也有一個類似的名叫NGPT項目,已于2003年中期放棄).



    下面拿RedHat
    Enterprise Linux 5.1(Linux kernel 2.6.18-53.e15,glibc 2.5)做下操作示例,首先用ps –ef|grep
    java|grep –v grep命令獲取一個java進程的pid,這里得到的javapid是2577,然后進行下面的操作:
    [root@tdy218 ~]# ps -Lp 2577 cu
    USER  PID   LWP  %CPU NLWP %MEM VSZ 
       RSS      TTY STAT  START  TIME   COMMAND
    root   2577 2577  0.0     52    
    24.2   863560 141148   ?     Sl      Oct18   0:09   java
    root   2577
    2578  0.0     52      24.2   863560 141148   ?     Sl      Oct18   0:00 
    java
    root   2577 2579  0.0     52      24.2   863560 141148   ?     Sl    
    Oct18   0:00   java
    .........................



    當然,還可以通過調試工具GDB(具體的用法,請參閱gdb的幫助)來獲得LWP號,不過不能看到CPU占用率。
    本文檔的目的是為了診斷java進程占用CPU異常過高故障的,使用ps命令看到的CPU%并非當前的CPU占用值,是個歷史值,要想獲得當前的、準確的CPU占用率,需用top命令(這里提醒大家,不要相信網上那些所謂的xxx命令詳解,最好還是看幫助,man
    xxx)。

    然后運行一個可以造成CPU占用很高(死循環等)的java
    web程序:
    關鍵代碼(好久沒寫代碼了,很A級的一段代碼):
    package
    tdy218.alg;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import
    java.io.IOException;

    public  class DeadLoop extends HttpServlet{

     
    public void init(ServletConfig config) throws ServletException
       {
        
        super.init(config);
       }

       public void service(HttpServletRequest
    request,HttpServletResponse response) throws IOException
       {
        
       try{
                 while(true){
                      
    Math.exp(Math.PI);  //求歐拉數e的π次冪.
                      }
                }
        
      catch(Exception e){
                 while(true){
                    
    Math.exp(Math.PI);
                     }
                }
        
    }
    }

    部署并運行.


    接著執行下面的命令:
    [root@tdy218 alone_domain]# top -Hp 2577 -d 1 -n 1
    Tasks:  53
    total,   2 running,  51 sleeping,   0 stopped,   0 zombie
    Cpu(s): 39.5%us,
    15.6%sy,  0.0%ni, 30.4%id, 14.2%wa,  0.1%hi,  0.3%si,  0.0%st
    ……………………
    PID
    USER     PR  NI  VIRT  RES  SHR S %CPU %MEM TIME+   UID COMMAND
    2577 root 
       15   0  612m 587m 1512 S  0.0 61.5   0:28.62    0         java   
    2580 root 22 0 612m 587m 1512 S 0.0 61.5 0:00.00 0 java
    2581 root     18   0  612m 587m 1512 S  0.0 61.5   0:00.00    0       
    java   
    2582 root     18   0  612m 587m 1512 S  0.0 61.5   0:00.00    0    
        java   
    ……………………
    2602 root     19   0  612m 587m 1512 S  0.0 61.5 
    0:00.00    0         java   
    2603 root    25   0  612m
    587m 1512 R 95.6 61.5   4:02.32    0         java   

    ……………………
    可以多執行幾次(更準確),并將結果輸出到一個文件中,可加"-b”參數.
    如果還想對CPU占用進行排序,可結合sort等排序命令(看sort命令的幫助).
    然后記下這個PID為2603的線程,并對該java進程做kill
    -3操作:
    kill -3 2577
    做完上面的操作,你將得到兩個重要的信息:一個是占用CPU最高的1個或多個pthread
    id(即上面的PID列,其實就是LWP對應的內核線程號)和Thread Dump信息(對于WebLogic
    Server來說,默認在標準輸出中,如果在啟動時指定了標準輸出重定向到一個文件中,那么請找從該文件中找到本次kill -3操作生成的Thread
    Dump的完整信息,另存到一個文本文件中,文件名自定)。

    三、RedHat Linux下HotSpot 和JRockit
    JVM異常CPU占用過高診斷
    從上一步拿到的占用CPU很高的1個或多個內核線程號(pid)和Thread Dump信息,根據WebLogic
    Server使用的JVM的供應商不同,分下面2個分析方法:
    1.使用的是Sun HotSpot
    JVM
    需將那個(些)內核線程號(pid)轉換成16進制的值,在Thread
    Dump信息信息中搜索nid等于該值的線程即可,如下:
    "ExecuteThread: '14' for queue:
    'weblogic.kernel.Default'" daemon prio=1 tid=0x09d11df0
    nid=0xa2b runnable [0x8a127000..0x8a1281a8]
            at
    java.lang.StrictMath.exp(Native Method)
            at
    java.lang.Math.exp(Math.java:234)
            at
    tdy218.alg.DeadLoop.service(DeadLoop.java:17)
            at
    javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        
       …………………
    由于JVM使用的glibc版本等原因,Sun HotSpot JVM 1.4.2 update
    11(包含該版本)的threaddump信息中不包含nid,這時需要升級Sun HotSpot JVM 1.4.2 update 11的小版本即可,如:
    update
    12,在1.4.2這個大版中,也是從這個版本開始支持發生OutOfMemoryError故障時生成HeadDump文件的。
    2.使用的是Oracle
    JRockit JVM
    只接拿那個(些)內核線程號(pid) 的值,在Thread Dump信息信息中搜索tid等于該值的線程即可(從 JRockit 的
    70SP4RP2 和 81SP2RP1 以后的版本起,就可實現此映射,Linux下WebLogic Server自帶的JRockit
    R26.3就是在他們之后的版本),因為JRockit JVM的Thread Dump信息中不包含nid的值,不過JRockit
    JVM提供一個更簡單的tid,等于那個(些)內核線程號(pid)的值,而且是十進制的,無需進行進制轉換。如下:
    "ExecuteThread: '14'
    for queue: 'weblogic.kernel.Default'" id=25 idx=0x32 tid=2603
    prio=5 alive, in native, daemon
        at <unknown>(???.c)@0xb7fc4402
     
      at ptWaitForEvent+45(:0)@0xb7e92b31
        at
    vmtWaitUntilNotSoftSuspended+70(:0)@0xb7e9e436
        at
    tsCheckTransitToJava+26(:0)@0xb7e9e50a
        at
    java/lang/StrictMath.exp(D)D(Native Method)
        at
    java/lang/Math.exp(D)D(Math.java:234)[optimized]
        at
    tdy218/alg/DeadLoop.service(Ljavax/servlet
       
    /http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V
       
    (DeadLoop.java:17)
         ………………………

    延伸閱讀:
    1.POSIX線程
    http://www.ibm.com/developerworks/cn/linux/theme/posix_thread/
    2.Linux線程模型比較Linux
    Threads和NPTL
    http://www.ibm.com/developerworks/cn/linux/l-threading.html
    3.Linux線程實現機制分析
    https://www.ibm.com/developerworks/cn/linux/kernel/l-thread/
    4.O'Reilly公司出版的《Understanding
    the Linux Kernel, 3rd Edition》Chapter 3. Processes中的: 3.1. Processes,
    Lightweight Processes, and Threads 和 3.4. Creating Processes
    posted on 2014-07-29 10:46 張金鵬 閱讀(166) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 久久精品国产精品亚洲艾| 国产精品免费看香蕉| 亚洲免费人成在线视频观看| 免费一级毛片在线播放放视频 | 亚洲av乱码一区二区三区香蕉| 97在线视频免费公开观看| 亚洲黄色在线观看视频| 5g影院5g天天爽永久免费影院| 亚洲中文无码a∨在线观看| 国内精品乱码卡1卡2卡3免费| 亚洲综合久久一本伊伊区| 欧洲黑大粗无码免费| 久久久久亚洲国产AV麻豆 | 一级做a爰片久久免费| 国产亚洲视频在线播放| 日本中文字幕免费高清视频| 亚洲一区二区三区电影| 中字幕视频在线永久在线观看免费 | www免费黄色网| 亚洲尹人九九大色香蕉网站| 久热中文字幕在线精品免费| 亚洲精品无码人妻无码| 亚洲国产一区明星换脸| 成人网站免费看黄A站视频| 亚洲午夜久久久久久尤物| 国内外成人免费视频| 黄色短视频免费看| 亚洲精品国产成人中文| 免费看的成人yellow视频| 一区二区三区免费视频观看| 久久av无码专区亚洲av桃花岛| 成人午夜性A级毛片免费| 一级做a爰片久久毛片免费陪| 亚洲AV无码久久精品蜜桃| 99久久免费精品国产72精品九九| 国产亚洲精品美女久久久久| 亚洲第一AV网站| 真实乱视频国产免费观看 | 日韩欧毛片免费视频| 产传媒61国产免费| 亚洲国产精品综合久久久|