Java虛擬機記憶體管理原理基礎入門

来源:http://www.cnblogs.com/bigshark/archive/2016/01/10/5119039.html
-Advertisement-
Play Games

Jdk:Java程式設計語言、Java虛擬機、Java API類庫。Jdk是用於支持Java程式開發的最小環境。Jre:Java API類庫中的Java SE API子集、Java虛擬機。Jre是支持Java程式運行的標準環境。Program Counter Register:較小的記憶體空間,可以看...


Jdk:Java程式設計語言、Java虛擬機、Java API類庫。

Jdk是用於支持Java程式開發的最小環境。

Jre:Java API類庫中的Java SE API子集、Java虛擬機。

Jre是支持Java程式運行的標準環境。

clip_image002

Program Counter Register:較小的記憶體空間,可以看作當前線程所執行的位元組碼的行號指示器。是唯一一個Java虛擬機規範中沒有規定OutOfMemoryError的區域。

VM Stack:生命周期和線程相同,它描述了Java方法執行的記憶體模型:每個方法在執行的同時都會創建一個棧幀用於存儲局部變數表、操作數棧、動態鏈接、方法出口等信息。

兩種異常:StackOverflowError、OutOfMemoryError

Native Method Stack:類似VM Stack,且Sun HotSpot直接合二為一!

Heap:最大的一塊記憶體,虛擬機啟動時創建,唯一目的就是存放對象實例的。

Method Area:存儲已被虛擬機載入的類信息、常量、靜態變數、即使編譯器編譯後的代碼等數據。Java虛擬機規範稱其為堆的邏輯部分,別名卻叫Non-Heap(非堆),或永久代

Runtime Constant Pool:方法區的一部分

Direcrt Memory:不是虛擬機運行時數據區的一部分,也不是虛擬機規範定義的記憶體區域。

 

對象的創建—關鍵字new

記憶體劃分方法:指針碰撞(堆記憶體規整,通過移動指針分配記憶體)、空閑列表(堆記憶體不規整,通過更新記憶體列表分配記憶體)。

TLAB(Thread Local Allocation Buffer):本地線程分配緩衝,對於所創建的線程都會分配一塊獨立的空間,避免記憶體分配衝突,提升記憶體分配效率。

對象的記憶體佈局:對象頭(Header)、實例數據(Instance Data)和對其填充(Padding)。

對象的訪問定位:Java程式通過棧上的reference(引用)數據來操作堆上的具體對象。

  方式:句柄和直接指針(Sun HotSpot)。

clip_image004

clip_image006

OutOfMemoryError異常實戰

工具:Eclipse Memory Analyzer

記憶體泄漏Memory Leak、記憶體溢出Memory Overflow

 

判斷對象是否死亡—堆記憶體

1、引用計數演算法:給對象添加一個引用計數器,每當有一個地方引用它是,計數器加1;當引用失效時,計數器減1;任何時刻計數器為0的對象就是不可能再被使用的。

2、可達性分析演算法:通過“GC Roots”對象作為起始點向下搜索,當一個對象到GC Roots沒有任何引用鏈相連,證明此對象是不可用的。

 

To be or not to be!

1、 使用上述演算法判斷對象是否使用;

2、 如果不再被使用,則標記並篩選;

    刷選是否有必要執行finalize()方法,如下情況不需要執行:

    l 對象沒覆蓋finalize()方法;

    l finalize()方法已經被虛擬機調用過;

3、 如果有必要執行,則把該對象放置在F-Queue隊列中;

4、 由一個虛擬機自動建立、低優先順序的Finalizer線程去執行它,即由虛擬機來觸發執行;

5、 GC對隊列中的對象會進行第二次標記,即給對象重新建立引用,就能移除回收集合;

註意:任何一個對象的finalize()方法都只會被系統調用一次!

 

方法區回收

主要兩部分:廢棄常量和無用的類

控制參數

-Xnoclassgc:關閉虛擬機對class的垃圾回收功能;

-verbose:class:監視有多少類被載入;

-XX:TraceClassLoading、-XX:TraceClassUnLoading:列印類被載入和卸載的過程信息;

註意:在大量使用反射、動態代理、CGLib等ByteCode框架、動態生成JSP以及OSGI這類頻繁自定義ClassLoader的場景都需要虛擬機具備類卸載的功能,以保證永久代不會溢出!

 

垃圾收集演算法

1、標記—清除演算法:容易產生記憶體碎片

2、複製演算法:堆被劃分成兩個不同的區域:新生代(Young) 主要是用來存放新生的對象、老年代(Old) 主要存放應用程式中生命周期長的記憶體對象。新生代 (Young)又被劃分為三個區域:Eden、From Survivor、To Survivor。

預設的,新生代(Young)與老年代(Old)的比例的值為1:2

預設的,Edem : from : to = 8 : 1 : 1

clip_image008

3、標記—整理演算法

4、分代收集演算法

HotSpot演算法實現GC

枚舉根節點:逐個檢查;(Stop The World,GC執行時必須停頓所有Java執行線程)

在OopMap協助下,HotSpot可以快速並準確地完成枚舉。

安全點:只有在安全點才能停頓開始GC

安全區域:安全點的擴展,在安全區域可以停頓開始GC

垃圾收集器:記憶體回收的具體實現。

GC日誌

GC常用參數

clip_image010

clip_image012

記憶體分配策略

1、對象優先在Eden分配:新生代GC(Minor GC)、老年代GC(Major GC/Full GC)

2、大對象直接進入老年代:

3、長期存活的對象將進入老年代:給每個對象定義一個年齡(Age)計數器。對象在Eden出生並經過第一次Minor GC後仍然存活,並且能被Survicor容納的話,將被移動到Survivor空間,並對象年齡設為1。對象在Survivor中每“熬過”一次Minor GC,年齡就增加1,當年齡增加到一定程度(預設15),晉升到老年代中。

4、動態對象年齡判定:虛擬機並不是永遠要求對象年齡到一定程度才能晉升老年代,如果在Survivor空間中相同年齡所有對象大小總和大於Survivor空間的一半,年齡大於或等於該年齡的對象就可以直接進入老年代。

5、空間分配擔保:老年代的連續空間大於新生代對象總大小或者歷次晉升的平均大小就會進行Minor GC,否則將進行Full GC。

工具

clip_image014

clip_image016

clip_image018

clip_image020

clip_image022

clip_image024

JDK1.5中,getAllStackTraces()用於獲取虛擬機中所有線程的StackTraceElement對象。

HSDIS:JIT生成代碼反彙編。

JConsole:Java監視與管理控制平臺,基於JMX。

VisualVM:多合一故障處理工具


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

-Advertisement-
Play Games
更多相關文章
  • 原文:http://dason.blog.51cto.com/658897/505312Apache虛擬主機配置(多個功能變數名稱訪問多個目錄)為了方便管理虛擬主機,我決定使用一種方法,那就是修改httpd-vhosts.conf文件。第一步首先要使擴展文件httpd-vhosts.conf生效:1. 打開...
  • 原文:http://www.cnblogs.com/weiquxiong/p/3545564.html註:對靜態函數或靜態成員的調用方式不做分析;以下提到的測試環境為vc6.0;調試程式時看到這樣的代碼:1 pObj->ClassName::Function();開始不理解為什麼要在“->”後加上類...
  • 剛剛開始學習Python,第一個編寫的程式。import osuser_file = open('use_file.txt', 'r')user_list = user_file.readlines()user_file.close()while True: lock_file = open(...
  • 本人小白菜逼一枚,,,,剛建立博客,也寫不了太深入的,就寫點上課的筆記什麼的。有錯誤希望廣大博友指出,我一定虛心學習接收改正。我的新浪郵箱:[email protected]我的QQ郵箱:[email protected]電腦網路部分今天主講的tcp和udp協議,這兩協議都是數據鏈路層下...
  • OK!第一篇博文!自賀一下!今日看了此書的前幾頁。嗯,說得挺全,基礎易懂。之前學過c++,但沒用過命令行編譯。本人用的VS里的編譯器,文件名是cl.exe,在VC目錄下。雖然有了編譯器,但並不能直接使用,要配置環境變數。寫個批處理文件,在裡面寫環境變數設置的代碼就行了,如下:@set PATH=D....
  • 直接使用JDBC一個非常普遍的問題是動態SQL。使用參數值、參數本身和數據列都是動態的SQL,通常非常困難。典型的解決方法是,使用一系列if-else條件語句和一連串討厭的字元串連接。對於這個問題,SQLMapAPI使用和mappedstatement非常相似的結構,提供了較為優雅的方法。這裡是一個...
  • 提要16 讀取轉換流17 寫入轉換流18 流操作規律-119 流操作規律-220 改變標準輸入輸出設備21 異常的日誌信息22 系統信息16 讀取轉換流字元流體系中的InputStreamReader,是位元組流通向字元流的橋梁:它使用指定的charset讀取位元組並將其解碼為字元。它使用的字元集可以由...
  • 問題描述 若一個數(首位不為零)從左向右讀與從右向左讀都一樣,我們就將其稱之為迴文數。 例如:給定一個10進位數56,將56加65(即把56從右向左讀),得到121是一個迴文數。 又如:對於10進位數87: STEP1:87+78 = 165 STEP2:165+561 = 726 STE...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...