歡迎訪問昆山寶鼎軟件有限公司網站! 設為首頁 | 網站地圖 | XML | RSS訂閱 | 寶鼎郵箱 | 后臺管理
?

新聞資訊

MENU

軟件開發知識

even hours or days 圖紙加密 in the future. 可以看到

點擊: 次  來源:寶鼎軟件 時間:2017-07-28

原文出處: scugxl的專欄

配景

某天發明客戶情況一直有OOM產生,并且是路線狀的內存增長. 較量郁悶.

 even hours or days 圖紙加密  in the future. 可以看到

Abstract

這個文章內里會描寫以下幾件工作:

1. 在Java中有OOM應該怎么闡明?
2. Java finalizer為什么會激發OOM?
3. 為什么不能利用Thread.stop

Java中產生OOM應該怎么闡明

大大都時候Java都做得足夠好. 可是沒步伐照舊有大概會有OutOfMemoryError(OOM) 產生. 那么我們應該怎么闡明一個OOM錯誤呢?

拿到內存轉儲

方法1:自動轉儲

當OOM產生時, Java可以自動實驗(best effort)生成一個堆轉儲.只需要你在啟動參數中加上如下參數:

-XX:+HeapDumpOnOutOfMemoryError

這種方法生成的文件會在java的事情目次內里, 名字叫 java_pidXXX.hprof

方法2:手動轉儲

有時候你已經可以發明某個Java歷程占用了許多內存了. 是時候手動導出一個堆內存了.
利用jmap. jmap是一個jdk自帶的東西, 在jdk/bin下面,

jmap -dump:format=b,file=heap.bin <pid>   
jmap -F -dump:format=b,file=heap.bin <pid>  強制導出

有一點很重要: 出于兼容性思量,必然利用和你運行JRE**運行版內情同**的jmap東西.

運用東西闡明

常見的內存闡明東西是Eclipse的Memory analyzer 和 Jvisualvm.

Eclispe memory analyzer/ MAT

這個是Eclipse推出的一個可視化內存闡明東西.

 even hours or days 圖紙加密  in the future. 可以看到

內里的許多組件都很好用:

1. histogram 列出每個class有幾多instance
2. Leak suspects 列出了東西以為大概有內存泄漏的處所.

好比Leak suspects頁面的下圖:

 even hours or days 圖紙加密  in the future. 可以看到

從上圖可以看出, Finalizer線程占用860M的內存, 約93%的空間.

假如這些尺度的頁面不能讓你獲得你存眷的對象, 可以回收OQL console. 就是上圖左上角第4個圖標.
回收OQL 我們可以做許多的工作, 好比列出Finalizer工具引用的哪些工具都是啥:
列出所有URLConnection的url:

SELECT f.referent.url.toString() FROM java.lang.ref.Finalizer f WHERE f.referent.toString().startsWith("sun.net.www.protocol.https.HttpsURLConnectionImpl")

 even hours or days 圖紙加密  in the future. 可以看到

mat的oql參考地點:http://help.eclipse.org/neon/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

更強大的Jvisualvm

jdk自帶的jvisualvm也可以闡明堆轉儲.

 even hours or days 圖紙加密  in the future. 可以看到

它提供了比MAT越發強大的闡明成果.

MAT是無法做到雷同于sql groupby filter, top 之類的操縱的. 可能越發巨大的查詢. 可是在jvisualvm我們可以實現很巨大的查詢:

好比下面的query可以實現: 我想查察Finalizer所引用的工具中, 前10個instance最多的class都是啥:

var counts = {};
var alreadyReturned = {};
top(
    filter(
        sort(
            map(heap.objects("java.lang.ref.Finalizer"),
                function (fobject) {
                    var className = classof(fobject.referent)
                    if (!counts[className]) {
                        counts[className] = 1;
                    } else {
                        counts[className] = counts[className] + 1;
                    }
                    return {string: className, count: counts[className]};
                }),
            'rhs.count-lhs.count'),
        function (countObject) {
            if (!alreadyReturned[countObject.string]) {
                alreadyReturned[countObject.string] = true;
                return true;
            } else {
                return false;
            }
        }),
        "rhs.count > lhs.count", 10);

大抵表明下:

heap.objects(“java.lang.ref.Finalizer”)指定了堆上這個類的所有instance;
在map中, 每個record被映射為具有2個屬性的工具:{string:className, count[className]}, 屬性string, 代表class名字, 屬性count代表它的instance個數;
在排序函數中rhs代表右邊的元素, lhs代表左邊的元素.
示例輸出(不是前面的heap,可是不影響撫玩)

 even hours or days 圖紙加密  in the future. 可以看到

jvisualvm的oql參考地點:https://visualvm.github.io/documentation.html (在內里的OQL部門)

Java Finalizer為啥會激發OOM

從前面的heap已經看到了, 有許多的instance都被Java中的Finalizer線程引用了.

什么是Finalizer

排列三305组选前后关系 幸运28最开奖结果查询 福建11选5乐选 江西十一选五走势图真准 期货配资网 北京快乐8奇偶走势图 群英会胆拖玩法介绍 广东快乐十分秘诀 短线股票推荐 排列三技巧规律和口诀 481河南体彩泳坛夺金