91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

Java項目中哪些情況會出現內存泄漏

發布時間:2020-11-30 15:40:15 來源:億速云 閱讀:165 作者:Leah 欄目:開發技術

這期內容當中小編將會給大家帶來有關Java項目中哪些情況會出現內存泄漏,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

內存泄漏代碼示例

第一個例子非常簡單–下面的Java代碼嘗試分配一個2M整數數組。當您編譯它并使用12MB的Java堆空間(Java-Xmx12m-OOM)啟動時,它將失敗java.lang.OutOfMemoryError:Java堆空間消息。有了13MB的Java堆空間,程序運行得很好。

class OOM {
 static final int SIZE=2*1024*1024;
 public static void main(String[] a) {
  int[] i = new int[SIZE];
  }
}

第二個也是更現實的例子是內存泄漏在Java中,當開發人員創建和使用新的對象(如new Integer(5))時,他們不必自己分配內存—這是由Java虛擬機(JVM)負責的。在應用程序的生命周期中,JVM會定期檢查內存中哪些對象仍在使用,哪些對象沒有使用。未使用的對象可以丟棄,內存可以回收并再次使用。這個過程稱為垃圾回收。JVM中負責收集的相應模塊稱為垃圾收集器(GC)。

Java的自動內存管理依賴于GC定期查找未使用的對象并將其刪除。簡單地說,java 內存泄露是指應用程序不再使用某些對象,但垃圾回收無法識別它的情況。因此,這些未使用的對象將無限期地保留在Java堆空間中。這起連環碰撞最終會觸發java.lang.OutOfMemoryError:Java堆空間錯誤。

構建一個滿足內存泄漏定義的Java程序相當容易:

class KeylessEntry {
 
  static class Key {
   Integer id;
 
   Key(Integer id) {
     this.id = id;
   }
 
   @Override
   public int hashCode() {
     return id.hashCode();
   }
  }
 
  public static void main(String[] args) {
   Map m = new HashMap();
   while (true)
     for (int i = 0; i < 10000; i++)
      if (!m.containsKey(new Key(i)))
        m.put(new Key(i), "Number:" + i);
  }
}

當您執行上面的代碼時,您可能希望它永遠運行而不會出現任何問題,假設天真的緩存解決方案只將底層映射擴展到10000個元素,除此之外,所有的鍵都已經存在于HashMap中。但是,實際上,由于Key類在hashCode()旁邊沒有適當的equals()實現,所以元素將繼續被添加。

結果,隨著時間的推移,隨著泄漏代碼的不斷使用,“緩存”結果最終會消耗大量Java堆空間。當泄漏的內存填滿堆區域中的所有可用內存,而垃圾回收無法清理它時java.lang.OutOfMemoryError:引發Java堆空間。

解決方案很簡單–添加與下面類似的equals()方法的實現,您就可以開始了。但在你找到病因之前,你肯定會失去一些珍貴的腦細胞。

@Override
public boolean equals(Object o) {
  boolean response = false;
  if (o instanceof Key) {
   response = (((Key)o).id).equals(this.id);
  }
  return response;
}

內存溢出怎么解決?

在某些情況下,分配給JVM的堆的數量不足以滿足在JVM上運行的應用程序的需要。在這種情況下,您應該只分配更多的堆—請參閱本章末尾的部分了解如何實現這一點。

然而,在許多情況下,提供更多的Java堆空間并不能解決問題。例如,如果應用程序包含內存泄漏,則添加更多堆只會推遲java.lang.OutOfMemoryError:Java堆空間錯誤。此外,增加Java堆空間量也會增加GC暫停的長度,從而影響應用程序的吞吐量或延遲。

如果您希望解決Java堆空間的底層問題,而不是掩蓋癥狀,那么您需要找出代碼的哪一部分負責分配最多的內存。換句話說,你需要回答以下問題:

  1. 哪些對象占據堆的大部分

  2. 在源代碼中分配這些對象

在這一點上,一定要在你的日歷中清除幾天(或者-在項目符號列表下面自動查看)。下面是一個粗略的流程大綱,可以幫助您回答上述問題:

  • 獲得安全許可,以便從JVM執行堆轉儲。“dump轉儲”基本上是堆內容的快照,您可以對其進行分析。因此,這些快照可能包含機密信息,如密碼、信用卡號碼等,因此出于安全原因,獲取此類轉儲甚至可能不可能。

  • 在適當的時候把垃圾處理掉。準備好獲取一些轉儲,因為當在錯誤的時間執行時,堆轉儲包含大量的噪聲,實際上可能是無用的。另一方面,每個堆轉儲都會完全“freezes凍結”JVM,所以不要占用太多,否則最終用戶將面臨性能問題。

  • 找一臺能裝垃圾的機器。當您的JVM使用例如8GB的堆時,您需要一臺大于8GB的機器來分析堆內容。啟動轉儲分析軟件(我們推薦Eclipse MAT,但也有同樣好的替代品)。

  • 檢測堆的最大使用者的GC根路徑。我們在這里的另一篇文章中討論了這一活動。這對初學者來說尤其困難,但實踐將使你了解結構和導航機制。

  • 接下來,您需要弄清楚源代碼中潛在危險的大量對象被分配到哪里。如果您對應用程序的源代碼有很好的了解,那么您將能夠在幾次搜索中做到這一點。

或者,我們建議使用plumber,這是唯一一個具有自動根本原因檢測功能的Java監控解決方案。在其他性能問題中,它包羅萬象java.lang.OutOfMemoryErrors并自動為您提供有關最需要內存的數據結構的信息。

Plumber負責在后臺收集必要的數據——這包括關于堆使用情況的相關數據(只有對象布局圖,沒有實際數據),還有一些甚至在堆轉儲中都找不到的數據。它還為您執行必要的數據處理—在運行中,只要JVM遇到java.lang.OutOfMemoryError. 這里有一個例子java.lang.OutOfMemoryError管道工事故警報:

Java項目中哪些情況會出現內存泄漏

無需任何其他工具或分析,您可以看到:

  • 哪些對象消耗的內存最多

  • 在哪里分配這些對象(它們中的大多數在MetricManagerImpl類中分配,第304行)

  • 當前引用這些對象的是什么(到GC根的完整引用鏈)

有了這些信息,您就可以放大潛在的根本原因,并確保將數據結構縮減到適合您的內存池的級別。

然而,當您從內存分析或閱讀plumber報告得出的結論是內存使用是合法的,并且源代碼中沒有什么可更改的,那么您需要允許JVM有更多的Java堆空間來正常運行。在這種情況下,更改JVM啟動配置并添加(或增加值,如果存在):

-Xmx1024m

上述配置將為應用程序提供1024MB的Java堆空間。可以使用g或g表示GB,m或m表示MB,k或k表示KB。例如,以下所有內容都相當于最大Java堆空間為1GB:

  java -Xmx1073741824 com.mycompany.MyClass
  java -Xmx1048576k com.mycompany.MyClass
  java -Xmx1024m com.mycompany.MyClass
  java -Xmx1g com.mycompany.MyClass

上述就是小編為大家分享的Java項目中哪些情況會出現內存泄漏了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

昌都县| 延庆县| 长沙市| 亳州市| 竹山县| 宾阳县| 鹤壁市| 朝阳市| 乌鲁木齐县| 西昌市| 湖南省| 周宁县| 吴旗县| 南召县| 黄陵县| 文化| 阜宁县| 万盛区| 板桥市| 乌兰察布市| 高阳县| 江陵县| 治县。| 平原县| 剑阁县| 德州市| 蛟河市| 太湖县| 遵化市| 金塔县| 禄丰县| 靖远县| 台南县| 吴川市| 丹东市| 兴业县| 敖汉旗| 泸定县| 内丘县| 塔河县| 重庆市|