中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決JAVA內存泄漏問題

發布時間:2021-07-14 13:42:13 來源:億速云 閱讀:144 作者:chen 欄目:開發技術

本篇內容介紹了“如何解決JAVA內存泄漏問題”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

目錄
  • 1、什么是內存泄漏

  • 2、內存泄漏的原因

  • 3、內存泄漏有哪些情況

    • 3.1 代碼中沒有及時釋放,導致內存無法回收。

    • 3.2 資源未關閉造成的內存泄漏

    • 3.3 全局緩存持有的對象不使用的時候沒有及時移除,導致一直在內存中無法移除

    • 3.4 靜態集合類

    • 3.5 堆外內存無法回收

    • 4、內存泄漏的解決辦法

    • 5、內存問題排查

      • 第一步 首先確認邏輯問題

      • 第二步:分析gc是否正常執行

      • 第三步 確認下版本新增代碼的改動,盡快從代碼上找出問題。

      • 第四步:開啟各種命令行和 導出 dump 各種工具分析

  • 總結:

    1、什么是內存泄漏

    內存泄漏是指無用對象(不再使用的對象)持續占有內存或無用對象的內存得不到及時釋放,從而造成內存空間的浪費稱為內存泄漏。隨著垃圾回收器活動的增加以及內存占用的不斷增加,程序性能會逐漸表現出來下降,極端情況下,會引發OutOfMemoryError導致程序崩潰。

    2、內存泄漏的原因

    JVM 虛擬機是使用引用計數法和可達性分析來判斷對象是否可回收,本質是判斷一個對象是否還被引用,如果沒有引用則回收。在開發的過程中,由于代碼的實現不同就會出現很多種內存泄漏問題,讓gc 系統誤以為此對象還在引用中,無法回收,造成內存泄漏。

    3、內存泄漏有哪些情況

    3.1 代碼中沒有及時釋放,導致內存無法回收。

    下面的代碼,因為是雙向鏈表,但是斷開的不夠徹底,prev節點依然引用這當前正在使用的節點,導致無法回收

    public class ListNode {
        int val;
        ListNode next;
        ListNode prev;
        ListNode() {
        }
        ListNode(int val) {
            this.val = val;
        }
        public ListNode(int val, ListNode next, ListNode prev) {
            this.val = val;
            this.next = next;
            this.prev = prev;
        }
    
        public static void main(String[] args) {
            ListNode curr = new ListNode(1);
            ListNode prev = new ListNode(2);
            ListNode next = new ListNode(3);
            curr.prev = prev;
            curr.next = next;
            curr.prev = null;
        }
    }
    public static void main(String[] args) {
            ListNode curr = new ListNode(1);
            ListNode prev = new ListNode(2);
            ListNode next = new ListNode(3);
            curr.prev = prev;
            curr.next = next;
            curr.prev = null;
        }
    }

    3.2 資源未關閉造成的內存泄漏

    各種連接,如數據庫連接、網絡連接和IO連接等,文件讀寫等,可以使用 try-with-resources 讀取完文件,自動資源釋放

    try (RandomAccessFile raf = new RandomAccessFile(filePath, "r");) {
            Image image = null;
    while((image = parseImage(raf)) != null){
                imageList.add(image);
            }
            return imageList;
    } catch(Exception e){
        log.error("parse file error, path: {},", path, e);
        return null;
    }

    3.3 全局緩存持有的對象不使用的時候沒有及時移除,導致一直在內存中無法移除

    3.4 靜態集合類

    如HashMap、LinkedList等等。如果這些容器為靜態的,那么它們的生命周期與程序一致,則容器中的對象在程序結束之前將不能被釋放,從而造成內存泄漏。生命周期長的對象持有短生命周期對象的引用,盡管短生命周期的對象不再使用,但是因為長生命周期對象持有它的引用而導致不能被回收。

    3.5 堆外內存無法回收

    堆外內存不受gc的管理,可能因為第三方的bug出現內存泄漏

    4、內存泄漏的解決辦法

    1.盡量減少使用靜態變量,或者使用完及時 賦值為 null。

    2.明確內存對象的有效作用域,盡量縮小對象的作用域,能用局部變量處理的不用成員變量,因為局部變量彈棧會自動回收;

    3.減少長生命周期的對象持有短生命周期的引用;

    4.使用StringBuilder和StringBuffer進行字符串連接,Sting和StringBuilder以及StringBuffer等都可以代表字符串,其中String字符串代表的是不可變的字符串,后兩者表示可變的字符串。如果使用多個String對象進行字符串連接運算,在運行時可能產生大量臨時字符串,這些字符串會保存在內存中從而導致程序性能下降。

    5.對于不需要使用的對象手動設置null值,不管GC何時會開始清理,我們都應及時的將無用的對象標記為可被清理的對象;

    6.各種連接(數據庫連接,網絡連接,IO連接)操作,務必顯示調用close關閉。

    5、內存問題排查

    沒有任何一個程序員想要出現這種問題,但是出現了問題也要解決,內存泄漏的主要表象就是內存不足,內存告警之后如何判斷是否有內存泄漏。

    第一步 首先確認邏輯問題

    查看內存中對象的數量和大小,判斷是否在合理的范圍,如果在合理的范圍內,增大內存配置,調整內存比例就可以了。

    命令:

    jmap -heap pid

    如何解決JAVA內存泄漏問題

    第二步:分析gc是否正常執行

    命令:

    jstat -gcutil <pid> 1000

    如何解決JAVA內存泄漏問題

    S0 — Heap上的 Survivor space 0 區已使用空間的百分比    
    S1 — Heap上的 Survivor space 1 區已使用空間的百分比    
    E — Heap上的 Eden space 區已使用空間的百分比    
    O   — Heap上的 Old space 區已使用空間的百分比    
    P   — Perm space 區已使用空間的百分比
    YGC — 從應用程序啟動到采樣時發生 Young GC 的次數
    YGCT– 從應用程序啟動到采樣時 Young GC 所用的時間(單位秒)    
    FGC — 從應用程序啟動到采樣時發生 Full GC 的次數
    FGCT– 從應用程序啟動到采樣時 Full GC 所用的時間(單位秒)    
    GCT — 從應用程序啟動到采樣時用于垃圾回收的總時間(單位秒)
    LGCC - 進行GC的原因(低版本jdk可能沒有這一列)

    從這里觀察gc是否異常,也可以根據這個進行jvm內存分配調優,來提高性能降低gc對性能的損耗

    第三步 確認下版本新增代碼的改動,盡快從代碼上找出問題。
    第四步:開啟各種命令行和 導出 dump 各種工具分析
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:OnError
    -XX:+ShowMessageBoxOnError

    推薦使用jprofile 進行本地分析,可以不用記住那么多命令。

    如何解決JAVA內存泄漏問題

    總結:

    現在的服務器內存雖然很大,但是且用且珍惜,不要等到出現問題了才知道后果,在開發中規范自己代碼,用完的對象及時釋放,減少垃圾對象。出現問題了也不要慌,仔細分析代碼,一切都是有原因的。

    “如何解決JAVA內存泄漏問題”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    河东区| 游戏| 灵寿县| 卓资县| 沛县| 长宁县| 陆川县| 得荣县| 隆德县| 高陵县| 巩留县| 彩票| 游戏| 霍林郭勒市| 黄石市| 运城市| 偏关县| 安国市| 洛宁县| 青州市| 江川县| 建水县| 荔浦县| 大竹县| 建阳市| 常州市| 济阳县| 烟台市| 阜阳市| 梁平县| 荣昌县| 安福县| 子洲县| 新郑市| 麟游县| 宁阳县| 大新县| 利川市| 天全县| 西藏| 新竹县|