讀Java性能權威指南(第2版)筆記13_堆記憶體下

来源:https://www.cnblogs.com/lying7/archive/2023/03/11/17204466.html
-Advertisement-
Play Games

1. 對象重用 1.1. 原因 1.1.1. 許多對象的初始化成本很高,權衡了增加的GC時間之後,還是重用對象的效率更高 1.2. 只適用於初始化成本很高且數量較少的一組對象 1.2.1. 被重用的對象會在堆中停留很長時間。如果堆中有大量對象,創建新對象的空間就更少了,因此GC操作會更頻繁。 1.3 ...


1. 對象重用

1.1. 原因

1.1.1. 許多對象的初始化成本很高,權衡了增加的GC時間之後,還是重用對象的效率更高

1.2. 只適用於初始化成本很高且數量較少的一組對象

1.2.1. 被重用的對象會在堆中停留很長時間。如果堆中有大量對象,創建新對象的空間就更少了,因此GC操作會更頻繁。

1.3. 方式

1.3.1. 對象池

1.3.1.1. 線程池化可以節省創建線程的時間

1.3.1.2. 在池中有少量對象並不會對GC效率產生太大影響,但堆中充滿池化對象時會大大減慢GC的速度

1.3.2. 線程局部變數

1.3.2.1. 隨機數生成器作為線程局部變數,可以節省使用隨機數種子創建生成器所需的時間

1.4. 特點

1.4.1. 初始化對象需要很長的時間

1.4.2. 共用的對象數量往往很少

1.4.2.1. 它們對GC操作的影響降到了最低,因為它們不足以減慢GC周期

1.5. 應用場景

1.5.1. 線程池

1.5.1.1. 線程初始化的成本很高

1.5.2. JDBC連接池

1.5.2.1. 資料庫連接初始化的成本很高

1.5.3. 大數組

1.5.3.1. 每個元素都必須初始化為基於0的預設值(null、0或false,視情況而定)

1.5.4. 原生NIO緩衝區

1.5.4.1. 無論緩衝區有多大,分配一個直接的java.nio.Buffer(調用allocateDirect()方法返回的緩衝區)都是成本很高的操作

1.5.4.2. 最好是創建一個大的緩衝區,然後通過按需切片的方式來管理緩衝區,以便在將來的操作中返回它們重新使用

1.5.5. 與安全相關的類

1.5.5.1. MessageDigest、Signature以及其他安全演算法的實例

1.5.6. 字元串編碼器和解碼器對象

1.5.7. StringBuilder幫助類

1.5.8. 隨機數生成器

1.5.8.1. Random類和(特別是)SecureRandom類的實例

1.5.9. 從DNS查詢中獲得的名字

1.5.9.1. 網路查詢的成本很高

1.5.10. ZIP編碼器和解碼器

1.5.10.1. 初始化成本並不是特別高,但是它們的釋放成本很高

1.5.10.2. 依賴對象終結(finalization)來確保它們使用的原生記憶體也被釋放了

2. 對象池

2.1. 大小可能很難設置正確

2.2. 不能直接讓對象退出作用域,程式員必須將對象返還到池中

2.3. 持有大量對象會降低GC的效率(有時會大幅降低)

2.4. 必然需要同步,如果對象被頻繁地刪除和替換,對象池可能會存在大量競爭

2.5. 普通類的大型對象池帶來的性能問題肯定會比解決的問題還多

2.6. 限流對池性能的影響是有利的,池允許對稀缺資源的訪問進行限流

3. 線程局部變數

3.1. 線上程內總是可用的,不需要顯式地歸還

3.2. 不能對資源的訪問進行限流

3.2.1. 除非線程數量本身可以起到限流的作用

3.3. 不需要同步

3.3.1. 只能在單個線程內使用

3.3.2. 使用ThreadLocalRandom類性能會更好

3.4. 如果線程和可重用對象之間有一一對應的關係,那麼線程局部變數更容易使用

4. 不確定引用

4.1. indefinite reference

4.2. 表示任何特殊類型的引用

4.2.1. 軟引用或弱引用

4.2.2. 實際上是一個對象實例

4.3. 更多地用於緩存耗時的計算或資料庫查詢的結果,而不是用於重用一個簡單對象

4.4. 對垃圾回收器的影響

4.4.1. 會導致應用程式使用更多的記憶體

4.4.2. 不確定引用被垃圾回收器回收至少需要兩個GC周期,這對垃圾回收器的影響更大

4.4.2.1. 在最壞的情況下,引用隊列不會被立即清理,而是需要經過很多GC周期後才會釋放一切對象

4.5. -XX:+PrintReferenceGC標誌

4.5.1. 看到處理引用所花費的時間

4.5.2. 預設為false

4.6. 不確定引用會消耗自身的記憶體,而且會長時間持有其他對象的記憶體,應儘量少用

5. 引用

5.1. reference

5.2. 一個引用(或對象引用)可以是任何類型的引用

5.3. 強引用、弱引用和軟引用等

6. 所引對象

6.1. referent

6.2. 將另一個引用(幾乎總是強引用)嵌入到不確定引用類的實例中。被封裝的這個對象被稱為所引對象

7. 軟引用

7.1. Soft Reference

7.2. 當相關對象在未來有很大概率被重用,而你想讓垃圾回收器回收最近沒有用到的對象時使用

7.2.1. 軟引用可以長期持有對象,它會提供一個簡單的、GC友好的LRU緩存

7.3. 本質上是一個大型的、最近最少使用的(LRU)對象池

7.4. 獲得良好性能的關鍵是要確保它被及時清理

7.5. 清理時機

7.5.1. 所引對象必須沒有被其他的強引用所引用

7.5.2. 軟引用是指向所引對象的唯一引用,那麼當軟引用最近沒有被訪問時,所引對象就會在下個GC周期被釋放

7.6. -XX:SoftRefLRUPolicyMSPerMB=N標誌

7.6.1. 預設值是1000

7.7. 長期運行的應用程式也可以考慮增加SoftRefLRUPolicyMSPerMB的值的條件

7.7.1. 堆中有大量空閑空間可用

7.7.2. 軟引用的訪問頻率不高

7.8. 不要使用過多的軟引用,它們很容易填滿整個堆

7.9. 當對象的數量不太多時,軟引用的效果才會好,否則,還是要考慮使用更傳統的、大小有界的對象池,並且以LRU緩存形式實現

8. 弱引用

8.1. weak reference

8.2. 在相關所引對象會被幾個線程同時使用時使用

8.3. 當強引用被清理時,弱引用立即被清理

8.4. 垃圾回收器在每個GC周期都會回收只有弱引用的對象

8.5. 集合類常常是記憶體泄漏的源頭

8.5.1. WeakHashMap和WeakIdentityMap

8.5.2. 基於不確定引用的集合可能很有用,但是應該謹慎使用

9. 終結器和最終引用

9.1. 不鼓勵使用終結器,應該使用新的Cleaner類

9.2. Object類的finalize()方法

9.2.1. 糟糕的方法,你應該儘量避免使用

9.2.2. 在JDK 11中被廢棄了

9.3. Cleaner(清理器)對象

9.3.1. 使用新的java.lang.ref.Cleaner類代替finalize()方法會容易很多

9.3.2. 在JDK 11中使用

9.3.3. 執行清理的對象不能包含指向需要被清理的對象的引用

9.3.3.1. 因為lambda太容易引用外部類了,不鼓勵開發人員使用lambda,而是要使用類

9.4. 如果你必須使用終結器,請確保將對象訪問的記憶體保持在最低限度

9.5. 使用另一種類型的不確定引用,而不是隱式地使用Finalizer引用

9.5.1. PhantomReference類(虛引用)

9.5.1.1. JDK 11使用

9.6. 終結器隊列

9.6.1. 當所引對象符合GC條件時,用來處理Finalizer引用的引用隊列

9.6.2. 命令來處理終結器隊列

9.6.2.1. % jcmd process_id GC.run_finalization

9.6.2.2. % jmap -finalizerinfo process_id

10. 普通對象指針

10.1. ordinary object pointer,oop

10.2. -XX:+UseCompressedOops

10.2.1. 對於4 GB到32 GB的堆,應該使用

10.2.2. 只要堆的最大大小小於32GB,標誌預設啟用

10.3. 使用了31 GB的堆並啟用了壓縮的oop的程式,通常比使用了33 GB堆的程式快

10.4. 最好使用小於32 GB的堆,或者至少比32 GB大幾個GB的堆

10.5. 一旦更多的記憶體被添加到堆中以彌補未壓縮的引用所使用的空間,GC周期的數量就會減少

10.6. 規劃至少38 GB的堆是一個好的開始


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文鏈接:為什麼 Go 語言 struct 要使用 tags 在 Go 語言中,struct 是一種常見的數據類型,它可以用來表示覆雜的數據結構。在 struct 中,我們可以定義多個欄位,每個欄位可以有不同的類型和名稱。 除了這些基本信息之外,Go 還提供了 struct tags,它可以用來指定 ...
  • 1.全局設置用戶名和郵箱 因為平時除了開發公司項目還會寫自己的項目或者去維護開源項目,一般情況下,公司會要求提交代碼時使用自己的真名或者拼音和公司郵箱,以前就只會設置全局用戶名或郵箱如下 git config --global user.name "username" git config --gl ...
  • 變數和數據類型 所有定義的變數都存在記憶體中,定義變數需要記憶體空間,不同類型的變數需要的記憶體空間是不同的 數據類型作用:告訴編譯器,我這個數據在記憶體中需要多大的空間,編譯器預算對象(變數)分配的記憶體空間大小。 1.常量與變數 1.1 常量 常量:程式運行中不能改變的量 整型常量:1 200 字元常量: ...
  • VS調試以及Qt基本使用 1.彙編語言 1.1 VS中C語言嵌套彙編代碼(瞭解) #include <stdio.h> int main() { //定義整型變數a, b, c int a; int b; int c; __asm { mov a, 3 //3的值放在a對應記憶體的位置 mov b, ...
  • 深夜檔分享,給大家介紹一個黑白的、“驚悚”的網站! 從名字來看(killed by microsoft),是不是猜到點端倪了? 這個神奇的網站居然收錄了微軟壽終正寢的那些軟體。這是一個免費的開放源碼列表,其中列出了已停產的微軟服務、產品、設備和應用程式。網站的目標是成為有關微軟已死項目歷史的真實信息 ...
  • 環境 odoo-14.0.post20221212.tar ORM API學習總結/學習教程 模型(Model) Model欄位被定義為model自身的屬性 from odoo import models, fields class AModel(models.Model): _name = 'a. ...
  • token解決cookie的弊端 cookie的弊端 **弊端一:**瀏覽器請求過伺服器後,下一次訪問時伺服器就會通過瀏覽器cookie中攜帶的sessionID去尋找對應session,但是如果伺服器做了負載均衡,用戶下一次請求可能會被定向到其他伺服器節點,那台伺服器上沒有用戶session信息, ...
  • C語言概述 1.什麼是C語言 C語言就是人和電腦交流的一種語言 語言是用來交流溝通的。有一方說,有另一方聽,必須有兩方參與,這是語言最重要的功能: 說的一方傳遞信息,聽的一方接收信息; 說的一方下達指令,聽的一方遵循命令做事情。 語言是人和人交流,C語言是人和機器交流。只是,人可以不聽另外一個人, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...