<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      MAT分析內存溢出- ShardingSphere JDBC的緩存泄露問題

      MAT分析Dump文件:
        1、設置MemoryAnalyzer.ini中的-Xmx為需要用的大小,否則會遇到打開dump文件報錯。。
        2、dump文件導出配置:在節(jié)點配置中增加dump導出
      -XX:+HeapDumpOnOutOfMemoryError 
      -XX:HeapDumpPath=/path/to/dump/heapdump.hprof
        3、dump文檔加載出來后,圖示如下:

       核心指標解析:
      • Histogram:直方圖,列出每個類的實例數(shù)量
        • Objects:對象個數(shù)
        • Shallow Heap:淺堆,表示對象占用多少內存。
        • Retained Heap:深堆,表示對象依賴的底層所有對象的總內存。
        • with outgoing references:此對象引用了哪些對象
        • with incoming references:此對象被誰引用  
      • Dominator Tree:支配樹,列出最大的對象以及它們使哪些對象保持存活。
      • Top Consumers:按類和包對最占用資源的對象進行分組打印。
      • Duplicate Classes:檢測由多個類加載器加載的類。
      • Leak Suspects:懷疑內存泄露
      • Top Components:列出占堆總大小超過 1% 的組件報告。
      • Component Report:組件報告,分析屬于同一個根包或類加載器的對象。
       可排查的問題類型:
      1. 內存泄漏(Memory Leak)
        • 特征:內存占用持續(xù)增長,最終觸發(fā)OutOfMemoryError
        • 常見場景:靜態(tài)集合未清理、監(jiān)聽器未移除、ThreadLocal使用不當、資源未關閉(流、連接)等。
      2. 內存溢出(OOM)
        • 堆內存不足:對象過多且無法回收。
        • 元空間 / 永久代溢出:類加載過多或常量池過大。
      3. 內存使用效率低
        • 大對象頻繁創(chuàng)建(如大字符串、大數(shù)組)導致 GC 頻繁。
        • 緩存設計不合理(如緩存未設置過期策略,導致對象堆積)。
      4. 線程相關問題
        • 線程泄漏(線程創(chuàng)建后未銷毀,持有大量資源)。
        • 死鎖或阻塞導致的資源無法釋放。
       排查流程:
      1、定位可疑區(qū)域:查看報告中的Leak Suspects,每個Suspect會【顯示可疑對象占用內存比例】;重點看Problem Suspect 1(最可能的泄漏點),記錄其對象類型(如java.util.HashMap)和支配樹路徑(如MyCache → HashMap → Entry[])。

         解析:org.springframework.boot.loader.LaunchedURLClassLoader @0x4c0005138 是一個類加載器,占用了約 2,014,349,632 字節(jié)(占比 67.97% ),這些內存主要是因為加載了 com.google.common.cache.LocalCache$Segment[] 這個實例導致的堆積。可能存在內存泄漏或者該部分對象占用內存過大的情況,需要進一步結合代碼里對 Guava Cache(即 com.google.common.cache 相關)的使用邏輯,比如緩存對象是否沒有合理失效、緩存配置的容量是否過大等,來排查為何會出現(xiàn)這么高的內存占用 。
        Keywords:關鍵信息,列出了關鍵的類和類加載器等標識,方便定位和關聯(lián)代碼及相關組件,com.google.common.cache.LocalCache$Segment[] 表明是 Guava 緩存的段數(shù)組相關,org.springframework.boot.loader.LaunchedURLClassLoader @0x4c0005138 是加載這些類的類加載器實例標識,可輔助在代碼和類加載機制層面去深挖問題根源 。點擊 Details 通常能查看更詳細的對象引用鏈、內存占用細節(jié)等,助力進一步分析內存問題。
      2、分析details:
       

         解析:
      1. 從引用鏈看LocalCache → loadingCache → sqlStatementCache ,說明是 ShardingSphere 的 SQL 語句解析緩存(SQLStatementParserEngine 相關) 在占用內存。
      2. 逐層展開后,最終關聯(lián)到 org.springframework.boot.loader.LaunchedURLClassLoader 加載的類(classes 節(jié)點),體現(xiàn)了類加載器持有緩存對象,導致內存無法釋放 。
      3. 下方多個線程(如 Log4j 線程、Tomcat 線程、ShardingSphere 元數(shù)據加載線程等)的 contextClassLoader 都指向 LaunchedURLClassLoader,說明 這些線程在運行時依賴該類加載器加載的類 。若線程未正確終止或類加載器未被釋放,會進一步延長緩存對象的生命周期,加劇內存占用。
        從這里就可以看出SQLStatementParserEngine 相關的內存占用非常大,
      3、跟蹤引用鏈with outgoing references

         關鍵路徑:SQLStatementParserEngineFactory → ENGINESConcurrentHashMap) → SQLStatementParserEngine → sqlStatementCache → LocalCache → segmentsLocalCache$Segment[])。這是 ShardingSphere SQL 解析緩存的完整引用鏈,segments 數(shù)組是內存堆積的直接載體(對應最初的 LocalCache$Segment[] 占用問題)。
        內存占比驗證:LocalCache 的 Retained Heap 高達 1,878,763,216(約 1.75GB),說明緩存對象確實在此大量堆積。
        以上只是為了從不同的區(qū)域去看,同樣也可以從直方圖去看,根據Retained Heap降序,找出top對象信息,并看引用鏈。
      4、結合業(yè)務代碼分析:
      • 組件關聯(lián):所有內存堆積都關聯(lián) SQLStatementParserEngine(ShardingSphere 負責 SQL 解析緩存的核心類)和 LocalCache(Guava Cache 實現(xiàn)),且 SQLStatementParserEngine 是 ShardingSphere JDBC 的內置組件,說明緩存邏輯由 ShardingSphere 觸發(fā)。
      • 緩存特性:ShardingSphere JDBC 默認會緩存 SQL 解析結果(通過 SQLStatementCache),若未合理配置緩存容量 / 過期時間,或業(yè)務場景中SQL 多樣性極高(如動態(tài)參數(shù) SQL 過多),就會導致緩存無限堆積,符合 “緩存泄漏” 特征(對象無法被 GC 回收,內存持續(xù)增長)。
      • 找到ShardingSphere 緩存配置的核心類,ShardingSphere JDBC 的 SQL 解析緩存由 SQLStatementParserEngine 管理,其緩存初始化邏輯在 SQLStatementParserEngineFactory 或 SQLStatementCache 相關類中。
        • 關鍵類路徑:org.apache.shardingsphere.infra.parser.sql.SQLStatementParserEngineorg.apache.shardingsphere.infra.parser.cache.SQLStatementCache(若存在)
        • 代碼定位:在項目依賴中找到 ShardingSphere JDBC 的源碼(或反編譯 Jar 包),搜索 CacheBuilder.newBuilder(),定位緩存創(chuàng)建邏輯,例如:ShardingSphere JDBC 對 SQL 解析緩存的配置,查找項目中 shardingsphere-jdbc 的配置文件,是否設置了 SQL 解析緩存的參數(shù):
      • /**
         * SQL語句解析引擎,負責SQL語句的解析和緩存管理
         * 核心作用是將原始SQL字符串解析為結構化的SQLStatement對象,同時提供緩存機制提升性能
         */
        public final class SQLStatementParserEngine {
            
            /**
             * SQL語句解析執(zhí)行器,實際執(zhí)行SQL解析的組件
             * 封裝了不同數(shù)據庫類型的SQL解析邏輯
             */
            private final SQLStatementParserExecutor sqlStatementParserExecutor;
            
            /**
             * SQL語句緩存,使用LoadingCache實現(xiàn)(通常是Guava的緩存實現(xiàn))
             * 鍵為SQL字符串,值為解析后的SQLStatement對象
             * 具備自動加載和過期淘汰能力
             */
            private final LoadingCache<String, SQLStatement> sqlStatementCache;
        
            /**
             * 構造方法,初始化解析引擎
             * 
             * @param databaseType 數(shù)據庫類型(如MySQL、PostgreSQL等)
             * @param sqlCommentParseEnabled 是否解析SQL中的注釋
             */
            public SQLStatementParserEngine(String databaseType, boolean sqlCommentParseEnabled) {
                // 初始化解析執(zhí)行器,傳入數(shù)據庫類型和注釋解析開關
                this.sqlStatementParserExecutor = new SQLStatementParserExecutor(databaseType, sqlCommentParseEnabled);
                
                // 構建SQL語句緩存
                // CacheOption參數(shù)說明:
                // 2000:緩存最大條目數(shù)(maximumSize)
                // 65535L:緩存過期時間(expireAfterWrite,單位根據實現(xiàn)可能為秒或毫秒)
                // 4:可能是并發(fā)級別(concurrencyLevel),允許同時寫入緩存的線程數(shù)
                this.sqlStatementCache = SQLStatementCacheBuilder.build(
                    new CacheOption(2000, 65535L, 4), 
                    databaseType, 
                    sqlCommentParseEnabled
                );
            }
        
            /**
             * 解析SQL語句的核心方法
             * 
             * @param sql 原始SQL字符串
             * @param useCache 是否使用緩存:true-優(yōu)先從緩存獲取,未命中則解析并緩存;false-直接解析不使用緩存
             * @return 解析后的SQLStatement對象(包含SQL結構化信息,如表名、條件、排序等)
             */
            public SQLStatement parse(String sql, boolean useCache) {
                // 根據useCache參數(shù)決定是否使用緩存
                return useCache 
                    ? (SQLStatement)this.sqlStatementCache.getUnchecked(sql)  // 使用緩存:從緩存獲取,無則自動加載
                    : this.sqlStatementParserExecutor.parse(sql);  // 不使用緩存:直接調用執(zhí)行器解析
            }
        }
        筆者項目中確實沒有這個配置的,但默認已有大小,那為什么還會大內存,分析這個緩存存的內容有:
      • Key:原始 SQL 字符串(如"SELECT * FROM t_order WHERE id = ?"
      • Value:解析后的SQLStatement對象(包含表、條件、排序等結構化信息,但不包含路由結果)
        以下情況會導致緩存被寫入:首次執(zhí)行新 SQL、緩存淘汰 / 過期后再次執(zhí)行 SQL 時自動寫入。那么緩存sql的大小就決定了sharding里緩存的大小,所以maximumSize的大小要去進行分析,如何配置。
      5、確認是否存在sql過大,通過直方圖,看到char數(shù)據的深堆大小最大,并繼續(xù)查看引用鏈 可以看到,大對象都是查詢的sql,當sql過大時,會間接導致sharding緩存過大。 因此對maximum-sized的大小設置,要根據業(yè)務SQL特征分析:平衡SQL多樣性、緩存命中率和內存占用,避免盲目配置過大(導致內存浪費)或過小(緩存失效頻繁)。
      SQL 多樣性低(如固定 SQL 模板,參數(shù)變化但 SQL 結構不變) 可適當增大,充分利用緩存 2000-5000
      SQL 多樣性高(如大量動態(tài)生成 SQL,結構頻繁變化) 需減小,避免無效緩存占用內存 500-1000
      高頻 SQL 占比高(少數(shù) SQL 執(zhí)行次數(shù)占總流量 80% 以上) 保證覆蓋高頻 SQL 即可,無需過大 1000-3000
      SQL 結構復雜(單條SQLStatement對象體積大) 適當減小,控制總內存占用 500-1500
      通過 ShardingSphere 的緩存統(tǒng)計(需開啟sql-parser.cache.statistics-enabled: true)和 JVM 監(jiān)控,動態(tài)調整參數(shù):
        • 緩存命中率
          • 計算公式:命中次數(shù) / (命中次數(shù) + 未命中次數(shù))
          • 合理閾值:建議≥70%。若低于 50%,說明緩存利用率低,需減小maximum-size
          • 示例:1000 次查詢中,800 次命中,則命中率 80%,配置合理
        • 緩存實際條目數(shù)
          • 若長期穩(wěn)定在maximum-size的 80% 左右,說明配置適中
          • 若長期遠低于maximum-size(如僅使用 500 條但配置 2000),建議下調
          • 若頻繁達到maximum-size且淘汰頻繁(可通過日志觀察 LRU 淘汰次數(shù)),可適當上調
        • 內存占用
          • 通過 JVM 監(jiān)控(如 JVisualVM)觀察SQLStatement對象總內存
          • 建議控制在 JVM 堆內存的 5%-10% 以內(如 4GB 堆內存中,緩存占用不超過 400MB)
      1. 初始配置:根據業(yè)務類型設置保守值(如 1000),并開啟緩存統(tǒng)計
        yaml
        spring:
          shardingsphere:
            props:
              sql-parser.cache.maximum-size: 1000
              sql-parser.cache.statistics-enabled: true
      2. 運行觀測:收集 3-7 天的生產數(shù)據,統(tǒng)計:
        • 系統(tǒng)中不同 SQL 的總數(shù)量(去重后)
        • 高頻 SQL(執(zhí)行次數(shù)前 20%)的數(shù)量
        • 緩存命中率和內存占用
      3. 動態(tài)調整:
        • 若高頻 SQL 數(shù)量為 800,可將maximum-size設為 1000(留 20% 冗余)
        • 若命中率低于 60% 且 SQL 多樣性高,下調至 500
        • 若內存占用過高(如單條SQLStatement達 10KB,1000 條即 10MB,可接受;若達 100KB,則需下調)
       最后:針對這個內存的優(yōu)化,不僅僅是排查問題后的參數(shù)優(yōu)化,從參數(shù)評估到SQL都進行了優(yōu)化,SQL的優(yōu)化是按照一定的規(guī)范,進行問題SQL的分類,并逐一進行修改優(yōu)化。具體SQL的規(guī)范和優(yōu)化案例,會單獨發(fā)布一篇博文
      posted @ 2025-07-21 21:30  難得  閱讀(160)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品国产亚洲AⅤ无码| 丰满少妇又爽又紧又丰满在线观看| 最新的国产成人精品2020| 国产永久免费高清在线观看| 国产精品内射在线免费看| 精品国产一区二区三区性色| 视频二区国产精品职场同事 | 亚洲精品乱码久久观看网| 久久国产精品乱子乱精品| 欧美疯狂三p群体交乱视频| 南溪县| 成人精品日韩专区在线观看| 激情五月天自拍偷拍视频| 偷偷做久久久久免费网站| 国产精品午夜福利精品| 久久天天躁狠狠躁夜夜躁2o2o| 久久久久免费看成人影片| 无线日本视频精品| 精品久久久久久无码人妻蜜桃| 国产农村老熟女乱子综合| 国产 另类 在线 欧美日韩| 精品无码久久久久久尤物| 日日摸夜夜添夜夜添国产三级| 在线观看成人年视频免费| 亚洲精品国精品久久99热| 狠狠亚洲狠狠欧洲2019| 久久精品不卡一区二区| 99热精品国产三级在线观看| 亚洲性日韩精品一区二区| 国产肥妇一区二区熟女精品| 日韩av无码精品人妻系列| 丰满无码人妻热妇无码区| 精品人妻伦一二三区久久aaa片| 亚洲欧美人成电影在线观看| 国产无套内射又大又猛又粗又爽 | 不卡一区二区国产在线| 久久久久国精品产熟女久色 | 婷婷六月天在线| 夜夜添无码试看一区二区三区| 国产成人亚洲日韩欧美| 欧洲熟妇色xxxxx欧美|