• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • JVM優化01

    標簽: jvm  java  linux

    1.為什么對JVM做優化

    在本地開發環境中我們很少會需要對JVM進行優化的需求,但是到了生產環境,我們可能將有下面的需求:

    • 運行的應用"卡住了",日志不輸出,程序沒有反應;
    • 服務器的CPU負載突然升高;
    • 在多線程應用下.如何分配線程的數量;

    2.JVM的運行參數

    2.1.三種參數類型

    JVM的參數類型分為三類,分別是:

    • 標準參數:
      • -help
      • -version
    • -X參數(非標準參數)
      • -Xint
      • -Xcomp
    • -XX參數(使用率較高)
      • -XX:newSize
      • -XX:+UseSerialGC

    2.2.標準參數

    JVM的標準參數,一般都是很穩定的,在未來的JVM版本中不會改變,可以使用java -help檢索出所有標準參數;

    java -help
    用法: java [-options] class [args...]
    (執行類)
    java [-options] -jar jarfile [args...]
    (執行 jar 文件)
    其中選項包括:
    -d32 使用 32 位數據模型 (如果可用)
    -d64 使用 64 位數據模型 (如果可用)
    -server 選擇 “server” VM
    默認 VM 是 server,
    因為您是在服務器類計算機上運行。

    -cp <目錄和 zip/jar 文件的類搜索路徑>
    -classpath <目錄和 zip/jar 文件的類搜索路徑>: 分隔的目錄, JAR 檔案
                  和 ZIP 檔案列表, 用于搜索類文件。
    -D<名稱>=<>
                  設置系統屬性
    -verbose:[class|gc|jni]
                  啟用詳細輸出
    -version      輸出產品版本并退出
    -version:<>
                  警告: 此功能已過時, 將在
                  未來發行版中刪除。
                  需要指定的版本才能運行
    -showversion  輸出產品版本并繼續
    -jre-restrict-search | -no-jre-restrict-search
                  警告: 此功能已過時, 將在
                  未來發行版中刪除。
                  在版本搜索中包括/排除用戶專用 JRE
    -? -help      輸出此幫助消息
    -X            輸出非標準選項的幫助
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度啟用斷言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的斷言
    -esa | -enablesystemassertions
                  啟用系統斷言
    -dsa | -disablesystemassertions
                  禁用系統斷言
    -agentlib:<libname>[=<選項>]
                  加載本機代理庫 <libname>, 例如 -agentlib:hprof
                  另請參閱 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<選項>]
                  按完整路徑名加載本機代理庫
    -javaagent:<jarpath>[=<選項>]
                  加載 Java 編程語言代理, 請參閱 java.lang.instrument
    -splash:<imagepath>
                  使用指定的圖像顯示啟動屏幕
    

    2.2.1.通過-D設置系統屬性參數

    public class TestJvm {
        public static void main(String[] args) {
            String str = System.getProperty("str");
            if(str == null){
                System.out.println("nulllll");
            }else {
                System.out.println(str);
            }
        }
    }
    

    image-20200523153926679

    2.2.2.-server與-client參數

    可以通過-server或-client設置jvm的運行參數;

    • 它們的區別是Server VM的初始堆空間會大一些,默認使用的是并行垃圾回收器,啟動慢運行塊;
    • Client VM相對來說會保守一些,初始堆空間會小一些,使用串行的垃圾回收器,它的目標是為了讓JVM的啟動速度更快,但運行速度會比Server模式慢;
    • JVM在啟動的時候會根據硬件和操作系統自動選擇使用Server還是Client類型的JVM;
      • 32位操作系統
        • 如果是Windows操作系統,不論硬件配置如何,都默認使用Client類型的JVM;
        • 如果是其他操作系統上,機器配置有2GB以上的內存同時有2個以上CPU的話默認使用Server模式,否則使用client模式;
      • 64為操作系統
        • 只有Server類型,不支持client類型;

    image-20200523155038820

    2.3.-X參數

    ?  ~ java -X
        -Xmixed           混合模式執行 (默認)
        -Xint             僅解釋模式執行
        -Xbootclasspath:<: 分隔的目錄和 zip/jar 文件>
                          設置搜索路徑以引導類和資源
        -Xbootclasspath/a:<: 分隔的目錄和 zip/jar 文件>
                          附加在引導類路徑末尾
        -Xbootclasspath/p:<: 分隔的目錄和 zip/jar 文件>
                          置于引導類路徑之前
        -Xdiag            顯示附加診斷消息
        -Xnoclassgc       禁用類垃圾收集
        -Xincgc           啟用增量垃圾收集
        -Xloggc:<file>    將 GC 狀態記錄在文件中 (帶時間戳)
        -Xbatch           禁用后臺編譯
        -Xms<size>        設置初始 Java 堆大小
        -Xmx<size>        設置最大 Java 堆大小
        -Xss<size>        設置 Java 線程堆棧大小
        -Xprof            輸出 cpu 配置文件數據
        -Xfuture          啟用最嚴格的檢查, 預期將來的默認值
        -Xrs              減少 Java/VM 對操作系統信號的使用 (請參閱文檔)
        -Xcheck:jni       對 JNI 函數執行其他檢查
        -Xshare:off       不嘗試使用共享類數據
        -Xshare:auto      在可能的情況下使用共享類數據 (默認)
        -Xshare:on        要求使用共享類數據, 否則將失敗。
        -XshowSettings    顯示所有設置并繼續
        -XshowSettings:all
                          顯示所有設置并繼續
        -XshowSettings:vm 顯示所有與 vm 相關的設置并繼續
        -XshowSettings:properties
                          顯示所有屬性設置并繼續
        -XshowSettings:locale
                          顯示所有與區域設置相關的設置并繼續
    
    -X 選項是非標準選項, 如有更改, 恕不另行通知。
    
    
    以下選項為 Mac OS X 特定的選項:
        -XstartOnFirstThread
                          在第一個 (AppKit) 線程上運行 main() 方法
        -Xdock:name=<應用程序名稱>"
                          覆蓋停靠欄中顯示的默認應用程序名稱
        -Xdock:icon=<圖標文件的路徑>
                          覆蓋停靠欄中顯示的默認圖標
    

    2.3.1. -Xint,-Xcomp,-Xmixed

    • 在解釋模式(interpreted mode)下,-Xint標記會強制JVM執行所有的字節碼,當然這會降低運行速度,通常低10被或更多;
    • -Xcomp參數與-Xint正好相反,JVM在第一次使用時會把所有字節碼編譯成本地代碼,從而帶來最大程度的優化;
      • 然而,很多應用在-Xcomp也會有一些性能損失,當然這比使用-Xint損失的少,原因是-Xcomp沒有讓JVM啟用JIT編譯器的全部功能.JIT編譯器可以對是否需要編譯做判斷,如果所有代碼都進行編譯的話,對于一些只執行一次的代碼就沒有意義了;
    • -Xmixed是混合模式,將解釋模式與編譯模式進行混合使用,由JVM自己決定,這是JVM默認的模式,也是推薦使用的模式;

    2.4. -XX參數

    -XX參數也是非標準參數,主要用于JVM調優和debug操作;

    -XX參數的使用有2種方式,一種是boolean類型,一種是非boolean類型;

    • boolean類型
      • 格式:-XX:[+-]<name>表示啟動或禁用屬性;
        • 如:-XX:+DisableExplicitGC表示禁用手動調用gc操作,也就是說調用System.gc()無效;
    • 非boolean類型
      • 格式:-XX:<name>=<value>表示屬性值為;
        • 如:-XX:NewRatio=1表示新生代和老年代的比值;

    2.5. -Xms與-Xmx參數

    • -Xms-Xmx分別是設置Jvm的堆內存的初始值大小和最大大小;

    • -Xmx2048m:等價于-XX:MaxHeapSize,設置JVM最大堆內存為2048M;

    • -Xms512m:等價于-XX:InitialHeapSize,設置JVM初始堆內存為512M;

    2.6.查看JVM的運行參數

    2.6.1.運行Java命令時打印參數

    運行Java命令時打印參數,需要添加-XX:+PrintFlagsFinal參數即可;

    image-20200523164424615

    由上述的信息可以看出,參數有boolean類型和數字類型,值的操作符是=:=,分別代表默認值和被修改的值;

    2.6.2.查看正在運行的JVM參數

    如果想要查看正在運行的JVM就需要借助于jinfo命令查看;

    首先我們可以使用jps -l查看所有的java進程;

    image-20200523170852254

    jinfo -flag <參數名> <進程id>
    

    如果我們想要查看某一參數的值,用法如上;

    3.JVM的內存模型

    3.1.JDK1.7的堆內存模型

    image-20200523171905462

    • Young年輕區

      Young區被劃分為三部分,Eden區和兩個大小嚴格相同的Survivor區.其中,Survivor區間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時復制對象用,在Eden區間變滿的時候,GC就會將存活的對象移到空閑的Survivor區間中,根據JVM的策略,在經過幾次垃圾收集后,仍然存活于Survivor的對象將被移動到Tenured區間;

    • Tenured年老區

      Tenured區主要保存生命周期長的對象,一般是一些老的對象,當一些對象在Young復制轉移一定的次數以后,對象就會被轉移到Tenured區,一般如果系統中用了application級別的緩存,緩存中的對象往往會被轉移到這一區間;

    • Perm永久區

      Perm代主要保存class,method,filed對象,這部分的空間一般不會溢出,除非一次性加載加載了很多的類,不過在涉及到了部署的應用服務器的時候,有時候會遇到java.lang.OutOfMemoryError : PermGen space的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署之后,類的class沒有被卸載掉,這樣就造成了大量的class對象保存在了perm中,這種情況下,一般重新啟動應用服務器可以解決問題;

    • Virtual區

      最大內存和初始內存的差值就是VIrtual區;

    3.2.JDK1.8的堆內存模型

    image-20200523173336941

    由上圖可以看出,jdk1.8的內存模型是由2部分組成,年輕代+年老代

    年輕代:Eden+2*Survivor

    年老代:OldGen

    在JDK1.8中變化最大的是Perm區,用Metaspace(元數據空間)進行了替換;

    需要特別說明的是:Metaspace所占用的內存空間不是在虛擬機內部,而是在本地內存空間中,這也是與1.7的永久代最大的區別所在;

    image-20200523173748767

    3.3.為什么要廢棄1.7中的永久區

    http://openjdk.java.net/jeps/122

    This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

    移除永久代是為融合HotSpot JVM與 JRockit VM而做出的努力,因為JRockit沒有永久代,不需要配置永久代。

    現實使用中,由于永久代內存經常不夠用或發生內存泄露,爆出異常java.lang.OutOfMemoryError: PermGen.基于此,將永久區廢棄,而改用元空間,改為了使用本地內存空間.

    3.4.通過jstat命令進行查看堆內存使用情況

    jstat可以查看堆內存各部分的使用量,以及加載類的數量.命令的格式如下:

    jstat [-命令選項] [vmid] [間隔時間/毫秒] [查詢次數];

    3.4.1.查看class加載統計

    [root@fechinchu ~]# jstat -class 1970
    Loaded  Bytes  Unloaded  Bytes     Time   
      8419 16681.0       64   140.9      12.12
    

    說明:

    • Loaded:加載class的數量;
    • Bytes:所占用空間大小;
    • Unloaded:未加載數量;
    • Bytes:未加載占用空間;
    • Time:時間;

    3.4.2.查看編譯統計

    [root@fechinchu ~]# jstat -compiler 1970
    Compiled Failed Invalid   Time   FailedType FailedMethod
        5794      3       0    12.63          1 com/google/inject/internal/cglib/core/$MethodWrapper$MethodWrapperKey$$$KeyFactoryByCGLIB$$e23ecb5d hashCode
    

    說明:

    • Compiled:編譯數量;
    • Failed:失敗數量;
    • Invalid:不可用數量;
    • FailedType:失敗類型;
    • FailedMethod:失敗的方法;

    3.4.3.垃圾回收統計

    [root@fechinchu ~]# jstat -gc 1970
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    1024.0 3584.0 640.0   0.0   462336.0 117410.8  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
      
    #也可以指定打印的時間和次數,每1s打印一次,共打印5次
    [root@fechinchu ~]# jstat -gc 1970 1000 5
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    1024.0 3584.0 640.0   0.0   462336.0 141790.5  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
    1024.0 3584.0 640.0   0.0   462336.0 141790.5  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
    1024.0 3584.0 640.0   0.0   462336.0 141790.5  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
    1024.0 3584.0 640.0   0.0   462336.0 141790.5  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
    1024.0 3584.0 640.0   0.0   462336.0 141790.5  68608.0    42911.8   50776.0 48703.4 6272.0 5686.6     56    1.026   3      0.254    1.280
    
    • S0C:第一個Survivor區的大小(KB);
    • S1C:第二個Survivor區的大小(KB);
    • S0C:第一個Survivor區的使用大小(KB);
    • S1C:第二個Survivor去的使用大小(KB);
    • EC:Eden區的大小(KB);
    • EU:Eden區的使用大小(KB);
    • OC:Old區大小(KB);
    • OU:Old區使用大小(KB);
    • MC:方法區大小(KB);
    • MU:方法區使用大小(KB);
    • CCSC:壓縮類空間大小(KB);
    • CCSU:壓縮類空間使用大小(KB);
    • YGC:年輕代垃圾回收次數;
    • YGCT:年輕代垃圾回收消耗時間;
    • FGC:老年代垃圾回收次數;
    • FGCT:老年代垃圾回收消耗時間;
    • GCT:垃圾回收消耗總時間;

    4.jmap的使用以及內存溢出分析

    4.1.查看內存使用情況

    [root@fechinchu ~]# jmap -heap 1970
    Attaching to process ID 1970, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.171-b11
    
    using thread-local object allocation.
    Parallel GC with 2 thread(s)
    
    Heap Configuration:
       MinHeapFreeRatio         = 0
       MaxHeapFreeRatio         = 100
       MaxHeapSize              = 1518338048 (1448.0MB)
       NewSize                  = 31981568 (30.5MB)
       MaxNewSize               = 505937920 (482.5MB)
       OldSize                  = 64487424 (61.5MB)
       NewRatio                 = 2
       SurvivorRatio            = 8
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       MaxMetaspaceSize         = 17592186044415 MB
       G1HeapRegionSize         = 0 (0.0MB)
    
    Heap Usage:
    PS Young Generation
    Eden Space:
       capacity = 473432064 (451.5MB)
       used     = 163087560 (155.53241729736328MB)
       free     = 310344504 (295.9675827026367MB)
       34.44793295622664% used
    From Space:
       capacity = 1048576 (1.0MB)
       used     = 655360 (0.625MB)
       free     = 393216 (0.375MB)
       62.5% used
    To Space:
       capacity = 3670016 (3.5MB)
       used     = 0 (0.0MB)
       free     = 3670016 (3.5MB)
       0.0% used
    PS Old Generation
       capacity = 70254592 (67.0MB)
       used     = 43941672 (41.906044006347656MB)
       free     = 26312920 (25.093955993652344MB)
       62.54633433783232% used
    
    22938 interned Strings occupying 1898992 bytes.
    

    4.2.查看內存中對象數量及大小

    image-20200523182715746

    #查看所有對象,包括活躍以及非活躍的
    jmap -histo <pid> | more
    
    #查看活躍對象
    jmap -histo:live <pid> | more
    

    對象說明:

    B:byte

    C:char

    D:double

    F:float

    I:int

    J:long

    Z:boolean

    [:數組

    [L+:類名 其他對象

    4.3.將內存使用情況dump到文件中

    有些時候我們需要將jvm當前內存中的情況dump到文件中,然后對它進行分析,jmap也是支持dump到文件中的.

    #用法
    jmap -dump:format=b,file=<dumpFileName> <pid>
    #示例
    jmap -dump:format=b,file=/tmp/dump.dat 1970
    

    image-20200523184233266

    4.4.通過jhat對dump文件進行分析

    image-20200523184338589

    #用法
    jhat -port <port> <file>
    

    之后我們就可以使用瀏覽器進行訪問了

    image-20200523184502697

    在最頁面的最下面有OQL功能

    image-20200523184617122

    4.5.通過MAT對dump文件進行分析

    ?  MacOS ./MemoryAnalyzer -data dump ~/Develop/dump.dat
    

    5.jstack的使用

    有些時候我們需要查看下jvm的線程執行情況,比如,發現服務器的CPU的負載突然增高了,出現了死鎖,死循環等,我們該如何分析呢?

    由于程序是正常運行的,沒有任何的輸出,從日志方面也看不出任何問題,所以就需要看jvm的內部線程執行情況,然后再進行分析查找出原因 了;

    jstack的作用就是將正在運行的jvm的線程情況進行快照,并且打印出來;

    jstack <pid>
    

    5.1.線程的狀態

    image-20200523210059563

    6.VisualVM工具的使用

    VisualVM,能夠監控線程,內存情況,查看方法的CPU時間和內存中對象,已被GC的對象,反向查看分配的堆棧(比100個String對象分別由哪幾個對象分配出來的);

    VisualVM使用簡單,幾乎0配置,功能還是比較豐富的,幾乎囊括了其他JDK自帶命令的所有功能;

    • 內存信息;
    • 線程信息;
    • Dump堆(本地進程);
    • Dump線程(本地進程);
    • 打開堆Dump.堆Dump可以用jmap來生成;
    • 打開線程Dump;
    • 生成應用快照(包含內存信息,線程信息等等);
    • 性能分析,CPU分析(各個方法調用時間,檢查哪些方法耗時多),內存分析(各類對象占用的內存,檢查哪些類占用內存多);

    6.1.啟動

    image-20200523213543202

    6.2.本地進程(略)

    6.3.遠程進程

    VisualJVM不僅是可以監控本地JVM進程,還可以監控遠程的JVM進程,需要借助于JMX技術實現;

    6.3.1.JMX介紹

    JMX(Java Management Extensions,即Java管理拓展)是一個為應用程序,設備,系統等植入管理功能的框架.JMX可以跨越一系列異構操作系統平臺,系統體系結構和網絡傳輸協議.靈活的開發無縫的系統,網絡和服務管理應用;

    6.3.2.監控遠程的tomcat

    #在tomcat的bin目錄下,修改catalina.sh,添加如下的參數
    
    JAVA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 - Dcom.sun.management.jmxremote.authenticate=false -
    Dcom.sun.management.jmxremote.ssl=false"
    
    #這幾個參數的意思是:
    #-Dcom.sun.management.jmxremote :允許使用JMX遠程管理 
    #-Dcom.sun.management.jmxremote.port=9999 :JMX遠程連接端口
    #-Dcom.sun.management.jmxremote.authenticate=false :不進行身份認證,任何用戶都可以連接 #-Dcom.sun.management.jmxremote.ssl=false :不使用ssl
    

    這個時候我們可以使用VisualJVM連接遠程tomcat;

    版權聲明:本文為fechinchu原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/fechinchu/article/details/106562525

    智能推薦

    【JVM】【01】內存模型

    https://docs.oracle.com/javase/8/docs/index.html 1.jdk、jre、jvm的架構圖 2.jdk跨平臺特性,不同系統使用不同版本的jdk包 一個class文件可以再不同的平臺執行得到相同的結果 3.jvm由三部分組成 類加載系統 運行時數據區(內存模型) 字節碼執行引擎 4.jvm的內存模型 https://docs.oracle.com/javas...

    JVM_01 簡介

    JVM的位置 一些JVM SUN Classic Exact VM HotSpot VM :HotSpot指熱點代碼探測技術 BEA JRockit:(BEA 已被Oracle收購) 專注于服務端應用,世界最快的jvm之一 IBM J9 Taobao JVM: 目前已經在淘寶、天貓上線,替換了Oracle官方JVM; Graal VM: Oracle 2018年4月公開,口號 Run Progra...

    jvm優化--myself

    1、JVM Server與Client運行模式 JVM Server模式與client模式啟動,最主要的差別在于:-Server模式啟動時,速度較慢,但是一旦運行起來后,性能將會有很大的提升.原因是:   當虛擬機運行在-client模式的時候,使用的是一個代號為C1的輕量級編譯器, 而-server模式啟動的虛擬機采用相對重量級,代號為C2的編譯器. C2比C1編譯器編譯的相對徹底,,服務起來之...

    JVM編譯優化

    在部分的商用虛擬機中,Java 程序最初是通過解釋器(Interpreter )進行解釋執行的,當虛擬機發現某個方法或代碼塊的運行特別頻繁的時候,就會把這些代碼認定為“熱點代碼”。為了提高熱點代碼的執行效率,在運行時,即時編譯器(Just In Time Compiler )會把這些代碼編譯成與本地平臺相關的機器碼,并進行各種層次的優化。 一.HotSpot 內的即時編譯器...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    猜你喜歡

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    精品国产乱码久久久久久蜜桃不卡