日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

将内存消耗减少20倍

發布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 将内存消耗减少20倍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這將是另一個故事,與我們分享有關內存相關問題的最新經驗。 該案例是從最近的客戶支持案例中提取的,在該案例中,我們遇到了一個行為異常嚴重的應用程序,該應用程序因生產中的OutOfMemoryError消息而死亡。 在連接了Plumbr的情況下運行應用程序之后,我們確定這次不會遇到內存泄漏。 但是仍然有一些嚴重的錯誤。

癥狀是通過監視某些數據結構的開銷的一項實驗功能發現的。 它給了我們一個信號,指出了源代碼中的一個特定位置。 為了保護客戶的隱私,我們使用合成樣本重新制作了案件,同時在技術上使其與原始問題相同。 隨時下載源代碼 。

我們發現自己盯著從外部源加載的一組對象。 與外部系統的通信是通過XML接口實現的。 這本身還不錯。 但是,集成實現細節分散在整個系統中(將收到的文檔轉換為XMLBean實例,然后在整個系統中使用)的事實可能并不是最明智的選擇。

本質上,我們正在處理延遲加載的緩存解決方案。 緩存的對象是人物:

// Imports and methods removed to improve readability public class Person { private String id; private Date dateOfBirth; private String forename; private String surname; }

不太可能消耗內存。 但是,當我們打開一些更多的細節時,情況看起來會變得有些酸。 也就是說,該數據的實現類似于上面的簡單類聲明。 相反,該實現使用了模型生成的數據結構。 使用的模型類似于以下簡化的XSD代碼段:

<xs:schema targetNamespace="http://plumbr.eu" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:string"/> <xs:element name="dateOfBirth" type="xs:dateTime"/> <xs:element name="forename" type="xs:string"/> <xs:element name="surname" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>

開發人員使用XMLBeans生成了在后臺使用的模型。 現在讓我們添加一個事實,即緩存應該容納多達130萬個Persons實例,并且我們為失敗奠定了堅實的基礎。

運行捆綁的測試用例表明,基于XMLBean的解決方案的130萬個實例將消耗大約1.5 GB的堆。 我們認為我們可以做得更好。

第一個解決方案是顯而易見的。 集成細節不應跨越系統邊界。 因此,我們將緩存解決方案更改為簡單的java.util.HashMap <Long,Person>解決方案。 以ID為鍵,以Person對象為值。 立刻我們發現內存消耗減少到214MB 。 但是我們還不滿意。

由于Map中的鍵本質上是數字,因此我們有所有理由使用Trove Collections來進一步減少開銷。 實現中的快速更改,我們已用TLongObjectHashMap <Person>替換了HashMap 。 堆消耗降至143MB 。

我們當然可以在這里停下來,但是出于工程方面的好奇心,我們不允許這樣做。 我們不禁注意到所使用的數據包含冗余信息。 出生日期實際上是在ID中編碼的,因此我們可以輕松地從給定的ID計算生日,而不是將其復制到其他字段中。

因此,我們更改了Person對象的布局,現在它僅包含以下字段:

// Imports and methods removed to improve readability public class Person { private long id; private String forename; private String surname; }

重新運行測試證實了我們的期望。 堆消耗降至93MB 。 但是我們仍然不滿意。

該應用程序在具有舊JDK6版本的64位計算機上運行。 默認情況下不壓縮普通對象指針。 切換到-XX:+ UseCompressedOops給了我們額外的勝利-現在我們的內存已減少到73MB 。

我們可以走得更遠,開始實習字符串或基于鍵構建b樹,但這已經開始影響代碼的可讀性,因此我們決定在這里停止。 21.5倍的堆減少應該已經足夠好了。

得到教訓?

  • 不要讓集成細節跨越系統邊界
  • 冗余數據將耗資巨大。 盡可能刪除冗余。
  • 原始人是您的朋友。 了解您的工具并學習Trove(如果您還沒有的話)
  • 注意JVM提供的優化技術

如果您對進行的實驗感到好奇,請隨時從此處下載使用的代碼 。 描述了用于測量的實用程序,并在此博客文章中提供了該實用程序。

參考: Plumbr博客博客上的JCG合作伙伴 Nikita Salnikov Tarnovski 減少了20倍的內存消耗 。

翻譯自: https://www.javacodegeeks.com/2013/06/reducing-memory-consumption-by-20x.html

總結

以上是生活随笔為你收集整理的将内存消耗减少20倍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。