Java記憶體以及GC

来源:http://www.cnblogs.com/willhua/archive/2016/10/20/5975726.html
-Advertisement-
Play Games

《深入理解Java虛擬機》第二三章摘要 Java記憶體區域與記憶體溢出 Java虛擬機中的記憶體分配圖: 各個區域的特性總結如下表: 補充說明: 當多線程情形下,可能多個線程要在堆上分配記憶體,那麼可能出現記憶體分配的同步問題,解決方案有兩個,一個就是同步記憶體分配動作;另一個就是採用TLAB,即在Java堆中 ...


《深入理解Java虛擬機》第二三章摘要

Java記憶體區域與記憶體溢出

Java虛擬機中的記憶體分配圖

各個區域的特性總結如下表:

   

補充說明:

  • 當多線程情形下,可能多個線程要在堆上分配記憶體,那麼可能出現記憶體分配的同步問題,解決方案有兩個,一個就是同步記憶體分配動作;另一個就是採用TLAB,即在Java堆中針對每個線程先預先分配一小塊線程私有的本地線程分配緩衝。這樣當線程需要分配記憶體時就在自己的TLAB上進行,從而避免同步的開銷。但是當TLAB分配滿重新分配TLAB時仍需要同步;
  • 判斷一個類是否屬於無用的類,“可以”被回收的條件為:1 該類所有的實例都已經被回收;2 載入該類的ClassLoader已經被回收; 3 該類對於的java.lang.Class對象沒有在任何地方被引用。註意,只是可以,而不是要被回收。

記憶體分配方式:虛擬機使用哪種方式由記憶體是否規整決定,而記憶體是否規整則由回收演算法決定。

  1. 指針碰撞:假設所有已經被分配的記憶體放在一邊,而空閑的放在另外一邊,二者中間則用一個指針來作為分界點,當需要分配記憶體時只需要移動該指針即可,這樣的方式稱為指針碰撞。使用此方法的有Serial、ParNew等帶Compact的回收器
  2. 空閑列表:虛擬機中已分配的記憶體和空閑的記憶體並不規整,處於相互交錯的情形,那麼就需要通過維護一個列表來表示哪些記憶體是可用,當需要分配記憶體時則需要通過查詢列表來查找可用大小的記憶體。這樣的方式稱為空閑列表。使用此方法的有CMS等這種基於Mark-Sweep演算法的回收器

對象在HotSpot虛擬機中的記憶體佈局如下表所示:

  

在Java規範中,對於reference類型只規定了一個指向對象的引用,但沒有規定通過何種方式去訪問引用的數據。因此對於不同的虛擬機也有不同的訪問方式,主要有兩種方式:

  1. 使用句柄:在Java堆中划出一塊區域作為句柄池來存儲句柄,一個句柄包括對象實例數據的指針以及對象數據類型的指針,reference中存儲的就是對象的句柄的地址。reference通過句柄來間接訪問對象。其好處在於:當對象移動時,只需要改動矩形中的指針即可,而相應的reference則不需要做變動;
  2. 直接訪問:reference存儲的是對象地址,通過reference就可以直接訪問數據。Java對中的數據對象中含有到對象數據類型的指針,比如上面提到的類型指針。此種方式的好處就是訪問速度快,相比使用句柄的方式而言少了一次指針定位的開銷。HotSpotVM使用的是此種方式。

兩種使用方式的圖示說明如下圖:圖片來源 http://www.th7.cn/Program/java/201604/846729.shtml

 

垃圾回收演算法

判斷一個對象是否死去,不可能再被用的演算法有兩種:

  1. 引用計數演算法:對於一個對象,其被引用的次數增加一次,則計數加1,當引用失效的時候就減1.當其計數為0時,則認為該對象死去。該演算法的特點是效率高,但是很難解決對象之間的相互引用問題。使用此演算法的有MS的COM技術以及Python等
  2. 可達性分析演算法:該演算法的核心就是從GC Roots開始,檢測所引用的所有對象。若一個對象到GC Roots之間沒有任何引用鏈,那麼認為該對象已死。使用此演算法的有Java、C#等。

可以作為GC Roots的對象有:

  • 虛擬機棧(棧幀中的本地變數表)中引用的對象
  • 方法區中類靜態屬性引用的對象
  • 方法區中常量引用的對象
  • Native方法中引用的對象

在Java中有四種引用強度

  • 強引用:強引用永遠不會被垃圾回收器回收
  • 軟引用:系統提供SoftReference類來表示,表示還有但是非必須的對象。其回收時機在於把若引用對象回收完之後記憶體還不夠,則回收此類引用,若還不夠,則OOM
  • 弱引用:通過WeakReference類來表示,此類引用只能生存到下一次垃圾回收之前。當垃圾收集器工作時,無論當前記憶體是否足夠都會回收掉只被弱引用關聯的對象。即只要發生了GC,弱引用必定被回收。其與已經沒有到GC Roots的引用鏈的區別在於:還是可以通過弱引用來訪問這些對象的,但是沒有引用鏈的對象則永遠不可能再被訪問到了。
  • 虛引用:通過PhantomReference來實現,其對對象的生存時間沒有任何影響,其存在的意義在於能在被虛引用引用的對象被回收的時候收到一個系統通知。

系統的GC工作流程如下圖所示,總的來說,一個對象被回收可能會經過兩次標記過程,並且可能在finalize方法中拯救自己以避免被回收。

    

    

 幾種典型的垃圾回收演算法

 

HotSpot VM中的垃圾回收演算法的具體實現細節:為了結果的準確,GC在掃描時是需要凍結所有線程的。目前主流的Java虛擬採取的都是準確式GC,即系統知道每個記憶體位置的數據到底是一個什麼數據類型,以HotSpot為例,它採取的是一個叫做OopMap的數據結構來實現這樣的映射記錄。有了這樣的信息,虛擬機就直接知道哪些地方存放著對象的引用,從而避免了對記憶體挨個的檢查,加快了GC掃描的速度。程式的每條指令都可能導致引用關係或者記憶體數據的變化,即會導致OopMap的變化,這樣的話,如果給每個指令都生成一個對應的OopMap數據那麼是相當占用空間的,於是提出了安全點的概念(SafePoint),即只有當每個線程都運行到線程對應的安全點時才進行GC掃描,從而也只要給安全點上的指令生成OopMap即可,這樣就減少了OopMap的數量。而安全點的選取要考慮到GC頻率與系統性能的綜合影響,一般選取方法調用、迴圈跳轉、異常跳轉等“具有讓程式長時間運行的特征”的點。為了讓線程都跑到安全點停頓下來以進行GC掃描,有搶先式中斷和主動式中斷兩種方式。這裡又有另外一個問題,如果遇到一個比如處於Sleep狀態的線程,那麼它是不會走動的,如果它恰好不是在一個安全點Sleep,那麼意味著它永遠不會走到安全點來,所以又提出了安全區域(SafeRegion)的概念。即在這個區域內的點都是安全點。線程進入安全點之後會標誌自己進入了安全區域,且必須等GC執行完了才會離開安全區域。

 

 各個垃圾回收器

 

幾條最普遍的記憶體分配規則

  • 對象優先分配在Eden區:當Eden區記憶體不夠的時候,系統將發起一次速度較快的Minor GC
  • 大對象直接進入老年代:對於較長的數組以及字元串等大對象,直接把他們分配在老年代區。因此,對於那種生命周期較短的大對象,很容引起GC,應該儘量避免。
  • 長期存活的對象將進入老年代:一個若在Survivor區經歷多次Minor GC還存活,預設15次,則將被移入老年代區。
  • 動態對象年齡判定:此條是結合上一條的,要是Survivor中相同年齡的所有對象的大小和超過Survivor的一半,那麼年齡大於或者等於該年齡的對象將移入老年代區,無需等到15次
  • 空間分配擔保:針對新生代的複製收集演算法。若參數容許,當執行Minor GC之後,若存活的對象無法全部放在Survivor中,那麼將把多的對象直接放入老年代區。若老年代也沒足夠的空間,那麼將發生Full GC以獲得更多空間

 


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

-Advertisement-
Play Games
更多相關文章
  • C#環境下,使用Selenium調用不同的瀏覽器,可以使用如下方法: 註意實現: 1、使用IE瀏覽器的時候要在該項目的bin\Debug或bin\Release目錄下添加IEDriverServer.exe文件。 用nuget獲取IEDriverServer.exe:Install-Package ...
  • 一、博客系統進度回顧 上一遍博客介紹到,系統已經實現到了發佈以及前臺佈局展示,接下來就是實現一些,詳情頁,留言、輪播圖管理、右側博文統計信息實現。 二、博客系統詳情頁實現 2.1先來看看詳情頁展示的效果 2.2實現控制器在前臺控制器中創建一個Blog的控制器,主要是展示博客分類以及詳情頁 Actio ...
  • 效果圖:(右下角拖拽改變窗體大小) 第一步:添加xaml代碼: 第二步:xaml.cs後臺代碼 聲明 下次更新(菜單縮放):效果圖 轉載請註明地址~謝謝 謝謝大家關註 ...
  • JQuery —— 一個js函數包 一、選擇器 1、基本選擇器 ①id選擇器:# ②class選擇器:. ③標簽名選擇:標簽名 ④併列選擇:用,隔開 ⑤後代選擇:用空格隔開 代碼用法展示: <title></title> <script src="js/jquery-1.7.2.min.js"></ ...
  • 最新用PetaPoco4.0做項目發現有個需求,就是比如說:在mvc表單中,只顯示部分欄位,一個表單還有其他狀態等欄位,沒有顯示到mvc頁面上 但是當MVC收集表單提交更新的時候,會發現會把資料庫中的一些未出現在MVC編輯頁面的欄位更新成null。 為瞭解決這個問題,現在修改下PetaPoco的源碼 ...
  • 上一章筆者介紹了關於WinForm環境。這一章筆者將繼續講WinForm。只不過更加的面向開發了。事實就是在學習工具箱裡面的控制項。對於WinForm開發來講,企業對他的要求並沒有那麼高。但是如果是游戲相關的話,不好意思!筆者覺得你可能選錯語言了。C++可能更合適你。有一點希望讀者們明白。下列講到的內 ...
  • 文檔目錄 本節內容: 配置ABP 替換內置服務 配置模塊 為一個模塊創建配置 替換內置服務 ABP在啟動時,提供基礎框架和模型來配置和模塊化。 置ABP 在預初始化事件中進行配置,示例: ABP進行了模塊化設計,不同的模塊都能配置ABP。例如,不同的模塊都能添加導航提供器把自己的菜單項加入到主菜單中 ...
  • 一、基本選擇器: ID選擇器:$("#id名稱") 例如:$("#div1").css("width","100px"); CLASS選擇器:$(".id名稱") 併列$("#id名稱,#id名稱") 後代$("#id名稱 名稱")二.過濾選擇器 第一個:$(".id名稱:first") 最後一個: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...