日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

seata之jvm参数解析

發布時間:2024/1/8 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 seata之jvm参数解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微信公眾號:我其實目前沒有耶
我是一個互聯網公司的螺絲釘;
魔術師耿

JVM啟動參數解析

  • 疑問1 :生產環境上常用哪些JVM參數進行設置;

  • 疑問2 :sh 啟動jar 包并配置JVM參數樣例怎么寫;

  • 疑問3 :dockerfile 怎么配置(seata 源碼的 distribution中有他們的Dockerfile配置)

  • 疑問4 :怎樣在IDEA中搜索 jdk中的源碼中的關鍵字

  • 今天以seata服務的啟動腳本seata-server.sh為例,進行分析 疑問1和疑問2

    exec "$JAVACMD" $JAVA_OPTS -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="$BASEDIR"/logs/java_heapdump.hprof -XX:+DisableExplicitGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -Xloggc:"$BASEDIR"/logs/seata_gc.log -verbose:gc -Dio.netty.leakDetectionLevel=advanced \-classpath "$CLASSPATH" \-Dapp.name="seata-server" \-Dapp.pid="$$" \-Dapp.repo="$REPO" \-Dapp.home="$BASEDIR" \-Dbasedir="$BASEDIR" \io.seata.server.Server \"$@"

    其中

    • exec “$JAVACMD” $JAVA_OPTS -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k
  • -server 第一個參數

  • -Xmx2048m heap最大值

  • -Xms2048m 堆初始值

  • -Xmn1024m 不是堆最小值,而是新生代的大小(Sun官方推薦配置為整個堆的3/8)
    -Xss512k Stack Space棧空間的大小 設置每個線程的堆棧大小。JDK5.0以后每個線程堆棧大小為1MB,以前每個線程堆棧大小為256K。

    -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m

  • -XX:SurvivorRatio=10 新生代分為Eden ,兩塊Survivor;計算Survivor大小, Eden:Survivor = 10,總大小為1024,10x+x+x=1024 x=85

    • -XX:-OmitStackTraceInFastThrow

      1、jvm啟動參數中沒有配置-XX:-OmitStackTraceInFastThrow,
      參數:OmitStackTraceInFastThrow字面意思是省略異常棧信息從而快速拋出。
      會引起error日志顯示不全的問題
      該文章貼上了JDK那一段源碼: https://blog.csdn.net/diaoliwei2/article/details/95966266

      2、OmitStackTraceInFastThrow和StackTraceInThrowable都默認為true。
      所以條件 (!StackTraceInThrowable || OmitStackTraceInFastThrow)為true,即JVM默認開啟了Fast Throw優化。

      如果想關閉這個優化,配置-XX:-OmitStackTraceInFastThrow,StackTraceInThrowable保持默認配置-XX:+OmitStackTraceInFastThrow即可。JVM只對幾個特定類型異常開啟了Fast Throw優化,這些異常包括: : NullPointerException
      ArithmeticException
      ArrayIndexOutOfBoundsException
      ArrayStoreException
      ClassCastException

      3、下面寫個循環調用空指針異常測試一下:在循環了2800多次后,還是能正常打出堆棧信息。再之后就簡化了異常輸出。

      4、修改JVM 啟動參數,添加OmitStackTraceInFastThrow后。循環7000次異常信息還是正常輸出。

    • -XX:-UseAdaptiveSizePolicy

      https://www.jianshu.com/p/7414fd6862c5
      AdaptiveSizePolicy(自適應大小策略) 是 JVM GC Ergonomics(自適應調節策略) 的一部分。
      如果開啟 AdaptiveSizePolicy,則每次 GC 后會重新計算 Eden、From 和 To 區的大小,
      計算依據是 GC 過程中統計的 GC 時間、吞吐量、內存占用量。
      JDK 1.8 默認使用 UseParallelGC 垃圾回收器,該垃圾回收器默認啟動了 AdaptiveSizePolicy。
      由 AdaptiveSizePolicy 引發的 GC 問題

    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath="$BASEDIR"/logs/java_heapdump.hprof

    • -XX:+DisableExplicitGC ##禁止代碼中顯示調用GC

      java nio中的direct memory,那么使用-XX:+DisableExplicitGC一定要小心,存在潛在的內存泄露風險
      最佳編程實踐是:暴露出釋放資源的接口,程序員使用完成后,顯示釋放,這樣就能夠避免堆內存和非堆內存資源的同步釋放的難題。
      RevisedObjectInHeap類中通過finalize()方法來釋放堆外內存的,閱讀源碼可以發現,NIO中direct memory的釋放并不是通過finalize(),
      而是通過sun.misc.Cleaner實現的
      cleaner = Cleaner.create(this, new Deallocator(base, cap));
      為什么不用finalize呢?因為finalize不安全,也非常影響性能。什么是sun.misc.Cleaner?這是個幽靈引用PhantomReference

    -XX:+CMSParallelRemarkEnabled ## 并行標記

    -XX:+UseCMSInitiatingOccupancyOnly
    -XX:CMSInitiatingOccupancyFraction=75 ##設定CMS在對內存占用率達到75%的時候開始GC

    UseCMSInitiatingOccupancyOnly如果不指定, 只是用設定的回收閾值CMSInitiatingOccupancyFraction, 則JVM僅在第一次使用設定值,后續則自動調整會導致上面的那個參數不起作用由于在垃圾收集階段用戶線程還需要運行,那也就還需要預留有足夠的內存空間給用戶線程使用, 因此CMS收集器不能像其他收集器那樣等到老年代幾乎完全被填滿了再進行收集, 需要預留一部分空間提供并發收集時的程序運作使用

    -Xloggc:"$BASEDIR"/logs/seata_gc.log ##
    -verbose:gc

    jvm參數-verbose:gc和-XX:+PrintGC有區別? 在官方文檔中有說明:兩者功能一樣,都用于垃圾收集時的信息打印。 -verbose:gc 穩定版本 -XX:+PrintGC 非穩定版本,可能在未通知的情況下刪除,在下面官方文檔中是-XX:-PrintGC。 參見:http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html 因為被標記為manageable,所以可以通過如下三種方式修改: 1、com.sun.management.HotSpotDiagnosticMXBean API 2、JConsole 3、jinfo -flag 參見:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

    -Dio.netty.leakDetectionLevel=advanced

    這句話報告有泄漏的發生,提示你用-D參數,把防漏等級從默認的simple升到advanced, 具體看到被泄漏的ByteBuf創建的地方和被訪問的地方。https://www.iteye.com/news/30866Netty里四種主力的ByteBuf, 其中UnpooledHeapByteBuf 底下的byte[]能夠依賴JVM GC自然回收; 而UnpooledDirectByteBuf底下是DirectByteBuffer,如Java堆外內存掃盲貼所述,除了等JVM GC, 最好也能主動進行回收;而PooledHeapByteBuf 和 PooledDirectByteBuf,則必須要主動將用完的byte[]/ByteBuffer放回池里, 否則內存就要爆掉。所以,Netty ByteBuf需要在JVM的GC機制之外,有自己的引用計數器和回收過程。一下又回到了C的冰冷時代,自己malloc對象要自己free。 但和C時代又不完全一樣,內有引用計數器,外有JVM的GC,情況更為復雜。2. 引用計數器常識 計數器基于 AtomicIntegerFieldUpdater,為什么不直接用AtomicInteger?因為ByteBuf對象很多,如果都把int包一層AtomicInteger花銷較大,而AtomicIntegerFieldUpdater只需要一個全局的靜態變量。 所有ByteBuf的引用計數器初始值為1。 調用release(),將計數器減1,等于零時, deallocate()被調用,各種回收。 調用retain(),將計數器加1,即使ByteBuf在別的地方被人release()了,在本Class沒喊cut之前,不要把它釋放掉。 由duplicate(), slice()和order(ByteOrder)所創建的ByteBuf,與原對象共享底下的buffer,也共享引用計數器,所以它們經常需要調用retain()來顯示自己的存在。 當引用計數器為0,底下的buffer已被回收,即使ByteBuf對象還在,對它的各種訪問操作都會拋出異常。3.誰來負責Release在C時代,我們喜歡讓malloc和free成對出現,而在Netty里,因為Handler鏈的存在,ByteBuf經常要傳遞到下一個Hanlder去而不復還,所以規則變成了誰是最后使用者,誰負責釋放。另外,更要注意的是各種異常情況,ByteBuf沒有成功傳遞到下一個Hanlder,還在自己地界里的話,一定要進行釋放。3.1 InBound Message 在AbstractNioByteChannel.NioByteUnsafe.read() 處,配置好的ByteBufAllocator創建相應ByteBuf并調用 pipeline.fireChannelRead(byteBuf) 送入Handler鏈。根據上面的誰最后誰負責原則,每一個Handler對消息可能有三種處理方式對原消息不做處理,調用 ctx.fireChannelRead(msg)把原消息往下傳,那不用做什么釋放。 將原消息轉化為新的消息并調用 ctx.fireChannelRead(newMsg)往下傳,那必須把原消息release掉。 如果已經不再調用ctx.fireChannelRead(msg)傳遞任何消息,那更要把原消息release掉。 假設每一個Handler都把消息往下傳,Handler并也不知道誰是啟動Netty時所設定的Handler鏈的最后一員,所以Netty會在Handler鏈的最末補一個TailHandler,如果此時消息仍然是ReferenceCounted類型就會被release掉。 不過如果我們的業務Hanlder不再把消息往下傳了,這個TailHandler就派不上用場。 3.2 OutBound Message 要發送的消息通常由應用所創建,并調用 ctx.writeAndFlush(msg) 進入Handler鏈。在每一個Handler中的處理類似InBound Message,最后消息會來到HeadHandler,再經過一輪復雜的調用,在flush完成后終將被release掉。3.3 異常發生時的釋放 多層的異常處理機制,有些異常處理的地方不一定準確知道ByteBuf之前釋放了沒有,可以在釋放前加上引用計數大于0的判斷避免異常;有時候不清楚ByteBuf被引用了多少次,但又必須在此進行徹底的釋放,可以循環調用reelase()直到返回true。4. 內存泄漏檢測所謂內存泄漏,主要是針對池化的ByteBuf。ByteBuf對象被JVM GC掉之前,沒有調用release()去把底下的DirectByteBuffer或byte[]歸還到池里,會導致池越來越大。而非池化的ByteBuf,即使像DirectByteBuf那樣可能會用到System.gc(),但終歸會被release掉的,不會出大事。Netty擔心大家一定會不小心就搞出個大新聞來,因此提供了內存泄漏的監測機制。Netty默認就會從分配的ByteBuf里抽樣出大約1%的來進行跟蹤。如果泄漏,會有如下語句打印: 引用LEAK: ByteBuf.release() was not called before it's garbage-collected. Enable advanced leak reporting to find out where the leak occurred. To enable advanced leak reporting, specify the JVM option '-Dio.netty.leakDetectionLevel=advanced' or call ResourceLeakDetector.setLevel()這句話報告有泄漏的發生,提示你用-D參數,把防漏等級從默認的simple升到advanced,具體看到被泄漏的ByteBuf創建的地方和被訪問的地方。 禁用(DISABLED) - 完全禁止泄露檢測,省點消耗。 簡單(SIMPLE) - 默認等級,告訴我們取樣的1%的ByteBuf是否發生了泄露,但總共一次只打印一次,看不到就沒有了。 高級(ADVANCED) - 告訴我們取樣的1%的ByteBuf發生泄露的地方。每種類型的泄漏(創建的地方與訪問路徑一致)只打印一次。 偏執(PARANOID) - 跟高級選項類似,但此選項檢測所有ByteBuf,而不僅僅是取樣的那1%。在高壓力測試時,對性能有明顯影響。實現細節 每當各種ByteBufAllocator 創建ByteBuf時,都會問問是否需要采樣,Simple和Advanced級別下,就是以113這個素數來取模(害我看文檔的時候還在瞎擔心,1%,萬一泄漏的地方有所規律,剛好躲過了100這個數字呢,比如都是3倍數的),命中了就創建一個Java堆外內存掃盲貼里說的PhantomReference。然后創建一個Wrapper,包住ByteBuf和Reference。Simple級別下,wrapper只在執行release()時調用Reference.clear()把Reference清理掉,Advanced級別下則會記錄每一個創建和訪問的動作。當GC發生,還沒有被clear()的Reference就會被JVM放入到之前設定的ReferenceQueue里。在每次創建PhantomReference時,都會順便看看有沒有因為忘記執行release()把Reference給clear掉,在GC時被放進了ReferenceQueue的對象,有則以 "io.netty.util.ResourceLeakDetector”為logger name,寫出前面例子里的Error級別的日日志。順便說一句,Netty能自動匹配日志框架,先找Slf4j,再找Log4j,最后找JDK logger


    -classpath “KaTeX parse error: Undefined control sequence: \ at position 12: CLASSPATH" \? ? -Dapp.name="s…KaTeX parse error: Undefined control sequence: \ at position 3: " \? ? -Dapp.repo="REPO”
    -Dapp.home=“KaTeX parse error: Undefined control sequence: \ at position 10: BASEDIR" \? ? -Dbasedir="BASEDIR”
    io.seata.server.Server
    “$@”

    怎么優化tomcat的jvm參數

    #修改JVM參數不直接修改 catalina.bat 和catalina.sh
    在catalina.sh同級目錄創建setenv.sh文件
    在里面修改jvm參數

    參看 https://www.iteye.com/blog/tdcq-1990666

    #!/bin/sh # ================================================================== echo "start set env" echo "$CATALINA_BASE"export CATALINA_OPTS="$CATALINA_OPTS -Xmx6144m -Xms4096m -Xmn2048m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_BASE/logs/ir_heapdump.hprof -XX:+DisableExplicitGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -Xloggc:$CATALINA_BASE/logs/ir_gc.log -verbose:gc "

    以seata 的dockerfile 為例 分析疑問3

    以檢索 case Deoptimization::Reason_null_check: 為例

    直接ctrl + h 搜索不到

    請教博文作者DreamTHT , 說是在 這個文件里 https://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/opto/graphKit.cpp ,

    牛掰, 我真不懂 c++

    參看這篇博文https://blog.csdn.net/daerzei/article/details/79717717

    • 修改 點擊菜單File --> Project Structure --> SDKs --> Sourcepath ,添加上本地源碼解壓吧路徑C:\dev\jdk\jdk_source
      此時可以編輯源碼添加注釋

    • 修改 點擊Setting --> Build,Execution,Deployment --> Debugger --> Stepping
      把Do not step into the classes中的ajva.*,javax.*取消勾選,其他的隨意
      此時可以debug對源碼打斷點
      你好,大神

    總結:

    ? seata的這些參數設置還真是挺有講究的呀…不愧是大廠的專家呀!!!

    接下來任務很重呀,我要把自己之前學會了,又丟掉的東西寫個博客記錄下來了。

    我說我是一個入行快10年的程序員,你敢新?該死該死。

    在此把我珍藏了多年的第一篇博文,獻給各位吧。 后續會不停更新。每周至少一篇吧。保底

    我是魔術師耿,一個IT行業的搬磚人。

    總結

    以上是生活随笔為你收集整理的seata之jvm参数解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。