欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談JVM之使用JFR解決內(nèi)存泄露

 更新時(shí)間:2021年06月03日 09:36:02   作者:flydean  
內(nèi)存泄露的主要原因就是java中的對象生命周期有長有短。如果長生命周期的對象引用了短生命周期的對象,就有可能造成事實(shí)上的內(nèi)存泄露。本文將介紹JVM之使用JFR解決內(nèi)存泄露。

簡介

雖然java有自動化的GC,但是還會有內(nèi)存泄露的情況。當(dāng)然java中的內(nèi)存泄露跟C++中的泄露不同。

在C++中所有被分配的內(nèi)存對象都需要要程序員手動釋放。但是在java中并不需要這個(gè)過程,一切都是由GC來自動完成的。那么是不是java中就沒有內(nèi)存泄露了呢?

要回答這個(gè)問題我們首先需要界定一下什么是內(nèi)存泄露。如果說有時(shí)候我們不再使用的對象卻不能被GC釋放的話,那么就可以說發(fā)生了內(nèi)存泄露。

一個(gè)內(nèi)存泄露的例子

我們舉一個(gè)內(nèi)存泄露的例子,先定義一個(gè)大對象:

public class KeyObject {
    List<String> list = new ArrayList<>(200);
}

然后使用它:

public class TestMemoryLeak {

    public static HashSet<Object> hashSet= new HashSet();

    public static void main(String[] args) throws InterruptedException {
        boolean flag= true;
        while(flag){
            KeyObject keyObject= new KeyObject();
            hashSet.add(keyObject);
            keyObject=null;
            Thread.sleep(1);
        }
        System.out.println(hashSet.remove(new KeyObject()));
    }
}

在這個(gè)例子中,我們將new出來的KeyObject對象放進(jìn)HashSet中。
然后將keyObject置為空。

但是因?yàn)轭愖兞縣ashSet還保留著對keyObject的引用,所以keyObject對象并不會被回收。

注意,最后一行我們加了一個(gè)hashSet.remove的代碼,來使用類變量hashSet。
為什么要這樣做呢?這樣做是為了防止JIT對代碼進(jìn)行優(yōu)化,從而影響我們對內(nèi)存泄露的分析。

使用JFR和JMC來分析內(nèi)存泄露

Flight Recorder(JFR)主要用來記錄JVM的事件,我們可以從這些事件中分析出內(nèi)存泄露。

可以通過下面的指令來開啟JFR:

java -XX:StartFlightRecording

當(dāng)然我們也可以使用java神器jcmd來開啟JFR:

jcmd pid JFR.dump filename=recording.jfr path-to-gc-roots=true

這里我們使用JMC來圖形化分析一下上面的例子。

開啟JMC,找到我們的測試程序,打開飛行記錄器。

可以看到我們的對象在飛行記錄器期間分配了4MB的內(nèi)存,然后看到整體的內(nèi)存使用量是穩(wěn)步上升的。

我們什么時(shí)候知道會有內(nèi)存泄露呢?最簡單的肯定就是OutOfMemoryErrors,但是有些很隱蔽的內(nèi)存泄露會導(dǎo)致內(nèi)存使用緩步上漲,這時(shí)候就需要我們進(jìn)行細(xì)致的分析。

通過分析,我們看到內(nèi)存使用在穩(wěn)步上漲,這其實(shí)是很可疑的。

接下來我們通過JVM的OldObjectSample事件來分析一下。

OldObjectSample

OldObjectSample就是對生命周期比較長的對象進(jìn)行取樣,我們可以通過研究這些對象,來檢查潛在的內(nèi)存泄露。

這里我們關(guān)注一下事件瀏覽器中的Old Object Sample事件,我們可以在左下方看到事件的詳情。

或者你可以使用jfr命令直接將感興趣的事件解析輸出:

jfr print --events OldObjectSample flight_recording_1401comflydeanTestMemoryLeak89268.jfr   > /tmp/jfrevent.log

我們看一個(gè)具體的輸出Sample:

jdk.OldObjectSample {

  startTime = 19:53:25.607

  allocationTime = 19:50:51.924

  objectAge = 2 m 34 s

  lastKnownHeapUsage = 3.5 MB

  object =  [

    java.lang.Object[200]

  ]

  arrayElements = 200

  root = N/A

  eventThread = "main" (javaThreadId = 1)

  stackTrace = [

    java.util.ArrayList.<init>(int) line: 156

    com.flydean.KeyObject.<init>() line: 11

    com.flydean.TestMemoryLeak.main(String[]) line: 17

  ]

}

lastKnownHeapUsage是heap的使用大小,從日志中我們可以看到這個(gè)值是一直在增加的。

allocationTime表示的是這個(gè)對象分配的時(shí)間。

startTime表示的是這個(gè)對象被dump的時(shí)間。

object表示的是分配的對象。

stackTrace表示的是這個(gè)對象被分配的stack信息。

注意,如果需要展示stackTrace信息,需要開啟-XX:StartFlightRecording:settings=profile選項(xiàng)。

從上面的日志我們可以分析得出,main方法中的第17行,也就是 KeyObject keyObject= new KeyObject(); 在不斷的創(chuàng)建新的對象。

從而我們可以進(jìn)行更深層次的分析,最終找到內(nèi)存泄露的原因。

以上就是淺談JVM之使用JFR解決內(nèi)存泄露的詳細(xì)內(nèi)容,更多關(guān)于JVM之使用JFR解決內(nèi)存泄露的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Nacos?Client的Bug解決方法記錄

    Nacos?Client的Bug解決方法記錄

    這篇文章主要為大家介紹了Nacos?Client的Bug解決方法記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • SpringBoot應(yīng)用jar包啟動原理詳解

    SpringBoot應(yīng)用jar包啟動原理詳解

    本文主要介紹了SpringBoot應(yīng)用jar包啟動原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • stream中使用peek一些陷阱避免及解決方法

    stream中使用peek一些陷阱避免及解決方法

    這篇文章主要為大家介紹了stream中使用peek一些陷阱避免及解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 安裝IDEA和配置Maven的步驟詳解

    安裝IDEA和配置Maven的步驟詳解

    這篇文章主要介紹了安裝IDEA和配置Maven的步驟詳解,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java的函數(shù)式編程詳解

    Java的函數(shù)式編程詳解

    用了這么久的Java8,我尋思這種話也好意思說出來嗎,難道自己是PythonBoy出身就是看不懂Java的理由嗎,身為一個(gè)合格的后端Boy不會還有人看不明白Java的函數(shù)式編程吧,接下來小編和大家淺聊一下Java的函數(shù)式編程,需要的朋友可以參考下
    2023-10-10
  • Java詳細(xì)分析sleep和wait方法有哪些區(qū)別

    Java詳細(xì)分析sleep和wait方法有哪些區(qū)別

    這篇文章主要介紹了Java中wait與sleep的講解(wait有參及無參區(qū)別),通過代碼介紹了wait()?與wait(?long?timeout?)?區(qū)別,wait(0)?與?sleep(0)區(qū)別,需要的朋友可以參考下
    2022-04-04
  • Java實(shí)現(xiàn)lucene搜索功能的方法(推薦)

    Java實(shí)現(xiàn)lucene搜索功能的方法(推薦)

    下面小編就為大家?guī)硪黄狫ava實(shí)現(xiàn)lucene搜索功能的方法(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問題及解決辦法(報(bào)數(shù)據(jù)重復(fù)Duplicate entry的問題)

    Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問題及解決辦法(報(bào)數(shù)據(jù)重復(fù)Duplicate entry的

    在開發(fā)中,我們經(jīng)常會有邏輯刪除和唯一索引同時(shí)使用的情況,但當(dāng)使用mybatis plus時(shí),如果同時(shí)使用邏輯刪除和唯一索引,會報(bào)數(shù)據(jù)重復(fù)Duplicate entry的問題,如何解決這個(gè)問題呢,小編給大家分享Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問題及解決辦法,一起看看吧
    2023-11-11
  • Activiti開發(fā)環(huán)境的搭建過程詳解

    Activiti開發(fā)環(huán)境的搭建過程詳解

    這篇文章主要介紹了Activiti開發(fā)環(huán)境的搭建過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java反射常用方法案例詳解

    java反射常用方法案例詳解

    Java反射指的是一個(gè)機(jī)制,這種機(jī)制可以在Java程序運(yùn)行時(shí)(動態(tài))實(shí)例化對象、讀寫屬性、調(diào)用方法,這篇文章主要介紹了java反射常用方法,需要的朋友可以參考下
    2023-06-06

最新評論