1. 程式人生 > >第三章 JVM記憶體回收區域+物件存活的判斷+引用型別+垃圾回收執行緒

第三章 JVM記憶體回收區域+物件存活的判斷+引用型別+垃圾回收執行緒

注意:本文主要參考自《深入理解Java虛擬機器(第二版)》

說明:檢視本文之前,推薦先知道JVM記憶體結構,見《第一章 JVM記憶體結構

1、記憶體回收的區域

  • 堆:這是GC的主要區域
  • 方法區:回收兩樣東西
    • 無用的類
    • 廢棄的常量
  • 棧和PC暫存器是執行緒私有區域,不發生GC

2、怎樣判斷物件是否存活

垃圾回收:回收掉死亡物件所佔的記憶體。判斷物件是否死亡,有兩種方式:

  • 引用計數法
    • 原理:給物件新增一個引用計數器,每當有一個地方引用它時,計數器值+1;引用失效時,計數器值-1
    • 實際中不用,不用的兩個原因
      • 每次為物件賦值時,都要進行計數器值的增減,消耗較大
      • 對於A、B相互引用這種情況處理不了(這一點是不用的主要原因)
  • 可達性分析(跟蹤收集)
    • 原理:從根集合(GC Roots)開始向下掃描,根集合中的節點可以到達的節點就是存活節點,根集合中的節點到達不了的節點就是將要被回收的死亡節點,如下圖中的A/B/C是存活節點,D/E是死亡節點:

    • 根集合中的節點包括:簡單來講,就是全域性性的引用(常量和靜態屬性)和棧引用(下邊第一、三)
      • Java棧中的物件引用(存在於區域性變量表中,注意:區域性變量表中存放的是基本資料型別和物件引用
        • 這是垃圾回收最多考慮的地方,所以有時,我們也會將死亡物件稱為"沒有引用指向的物件"
      • 方法區中:常量+靜態(static)變數
      • 傳到本地方法中,還沒有被本地方法釋放的物件引用

3、3種引用型別

  • 強引用(Strong Reference):A a = new A();//a是強引用
  • 軟引用(Soft Reference):當記憶體不足時,釋放軟引用所引用的物件;當記憶體足夠時,就是一個普通物件(強引用)
  • 弱引用(Weak Reference):弱引用物件只能存活到下一次垃圾回收之前,一旦發生垃圾回收,立刻被回收掉

4、方法區的回收

  • 廢棄常量:例如,沒有任何一個引用指向常量池中的"abc"字串,則"abc"字串被回收
  • 無用的類:滿足以下三個條件
    • Java堆中不存在該類的任何例項
    • 載入該類的ClassLoader被回收
    • 該類的Class物件沒有在任何地方被引用

注意:

  • 在實際開發中,儘量不用JSP去做前端,而是用velocity、freemarker這樣的模板引擎去做
  • 與類相關常用的三個引數:
    • -XX:+PrintClassHistogram:輸出類統計狀態
    • -XX:-TraceClassLoading:列印類載入資訊
    • -XX:-TraceClassUnloading:列印類解除安裝資訊 View Code

5、垃圾回收執行緒

系統的垃圾回收是由垃圾回收執行緒來檢測操作的,該執行緒是一個後臺執行緒(daemon thread)。

5.1、後臺執行緒與我們使用的前臺執行緒而言,有一個特點:當JVM中的前臺執行緒數量為0時,後臺執行緒自動消亡。可以這樣講,後臺執行緒依託於前臺執行緒而存在。

5.2、垃圾回收執行緒為什麼要設定成為後臺執行緒呢?

我們想一下,當前臺一個執行緒都沒有時,垃圾還會有嗎?或者說垃圾回收還有必要嗎?答案是沒有必要,所以此時垃圾回收執行緒也就失去了存活的意義。

所以可以這樣講,將一個執行緒是否設定為後臺執行緒,就看這條執行緒在沒有其他執行緒存在的情況下,是否還有存活的意義

例如,在我們使用Apache mina2做RPC時,我們在訊息的接收端直接開啟一個後臺執行緒啟動服務來接受訊息傳送端發來的訊息事件請求就可以。試著去想,如果在整個JVM中只有當前的這一個後臺執行緒了,那麼這個執行緒還有必要存活下來嗎?當然沒有必要,因為訊息永遠都不會再發送了(前臺執行緒都沒了)

相關推薦

JVM記憶體回收區域+物件存活判斷+引用型別+垃圾回收執行

注意:本文主要參考自《深入理解Java虛擬機器(第二版)》 說明:檢視本文之前,推薦先知道JVM記憶體結構,見《第一章 JVM記憶體結構》 1、記憶體回收的區域 堆:這是GC的主要區域 方法區:回收兩樣東西 無用的類 廢棄的常量 棧和PC暫存器是執行緒私有區域,不發生GC

JVM記憶體回收區域+物件存活判斷+引用型別+垃圾回收執行

此文已由作者趙計剛薪授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 注意:本文主要參考自《深入理解Java虛擬機器(第二版)》 說明:檢視本文之前,推薦先知道JVM記憶體結構,見《第一章 JVM記憶體結構》 1、記憶體回收的區域 堆:這是GC的主要區域 方法區:回收兩樣東西

怎樣使用類和物件

3.1 首先不能在類的宣告中對資料成員進行初始化,因為類只是一種抽象型別並不是一個實體,不佔用儲存空間, 故無法存放資料。 如果一個類中的資料成員全部(must)都是public的,則可以在定義物件時進行初始化 Time t1 = {12,0,0};//全部資料成員 否則我們就需要用類似se

C++基礎(使用類和物件)上篇

利用建構函式對類物件初始化 在類內如果資料成員是公有的則可以在類內直接進行初始化 #include<iostream> using namespace std; class Time { public : int hour = 1; int m

C++基礎(使用類和物件)中篇(物件陣列,物件指標,常物件

一.1,物件陣列 我們定義普通型別的陣列時 int a[100]; char b[100]; string s[100]; 定義物件陣列也是一樣的 Student stud[5]; //定義stud陣列,有5個元素 物件陣列的初始化 Student

Spring Boot 基礎系列教程 | 十二篇:使用@Async實現非同步呼叫:自定義執行

推薦 Spring Boot/Cloud 視訊: 在之前的Spring Boot基礎教程系列中,已經通過《Spring Boot中使用@Async實現非同步呼叫》一文介紹過如何使用@Async註解來實現非同步呼叫了。但是,對於這些非同步執行的控制是我們保障自身

JavaScript高階程式設計(版)學習筆記(四)JavaScript引用型別

1、引用型別 引用型別是指封裝了變數和對應函式的結構體,它是例項就是物件,類似於C++、Java中的類,但沒有類的介面等。 建立方式一: var obj = new Object();//new關鍵字 + 建構函式 obj.name = "noodles"

《深入理解Java虛擬機器—JVM高階特性與實踐 周志明 著》之2 Java記憶體區域記憶體溢位異常

1、Java虛擬機器所管理的記憶體包括以下幾個執行時資料區域: 2、程式計數器:          1. 可以看作是當前執行緒所執行的位元組碼的行號指示器,是一塊較小的記憶體空間;  &nbs

JVM 2 Java記憶體區域記憶體溢位異常

可以參考下,這個寫的簡練 https://blog.csdn.net/seu_calvin/article/details/51404589 1 概述 對於java程式設計師來說,在虛擬機器自動記憶體管理機制的幫助下,不需要為每一個new操作去寫配對的delete/free程式碼,不

深入理解JVM垃圾收集器與記憶體分配策略

概述 對於Java記憶體執行時區域的各位部分,其中程式計數器、虛擬機器棧、本地方法棧這三個區域都是隨執行緒而生,隨執行緒而滅。並且棧幀中分配的記憶體也是在編譯後就已知的。因此這幾個區域的記憶體分配和回收都具備確定性,所以我們在這幾個區域就不必過多地考慮

筆記:深入理解JVM 2 Java記憶體區域記憶體溢位

1、JVM 執行時資料區 所有執行緒共享的資料區:方法區(持久代)、堆區 執行緒隔離的資料區:程式計數器、Java虛擬機器棧區 堆區構成:新生代 ( 由Eden, From Survivor, To Survivor 構成)、老生代 執行時常量池:方法區一部分,用於存放編

JVM歷險記:遇到了回收大法師

從五大部落到遇到根的迷,在記憶體裡面已經有些日子了。前兩天遇到了各種法師,專門回收死亡的物件。。。只看法師口中默唸¥¥$$7&&.就看一道金光從根出發遍及各個相連的物件。。。。然後使出所謂的三板斧:對於不同部分的堆資料使用不同的技法第一招叫做標記清除大法:這招

組合語言暫存器(記憶體訪問)

3.1  在CPU中,用一個16位暫存器來儲存一個字,一個字兩個位元組,高8位存放高位位元組,低8位存放低位位元組,低位元組所在的記憶體單元稱為起始地址。 3.2 3.3 8086CPU中,通常用DS暫存器來存放要訪問資料的段地址(字或者位元組) 舉個例子: mov bx,1000H mov

《SQL入門經典》筆記(:建立資料庫之管理資料庫物件

1. 什麼是資料庫物件? 資料庫物件用於儲存或引用資料,需要被定義,例如表、試圖、簇、序列、索引和異名(讓表具有另一個名稱)。   2. 什麼是規劃? 規劃是與資料庫某個使用者名稱相關聯的資料庫物件集合。相應的使用者名稱被稱為“規劃所有人”/“關聯物件組的所有人”。 同

暫存器(記憶體訪問)相關內容總結

      在本章中,我們從訪問記憶體的角度繼續學習了幾個暫存器。我們提出字單元的概念:字單元,即存放一個字型資料(16位)的記憶體單元,由兩個地址連續的記憶體單元組成。高地址記憶體單元中存放字型資料的高位位元組,低地址記憶體單元中存放字型資料的低位位元組。CPU要讀寫一個記憶體

棧作業題2-棧及其應用-計算機17級 6-1 爆記憶體函式例項 (6 分)

6-1 爆記憶體函式例項 (6 分) 本題要求實現一個遞迴函式,使用者傳入非負整型引數n,使用者依次輸出1到n之間的整數。所謂遞迴函式就是指自己呼叫自己的函式。 說明: (1)遞迴函式求解問題的基本思想是把一個大規模問題的求解歸結為一個相對較小規模問題的求解, 小規模

現代作業系統: 記憶體管理

作業系統的工作是將這個儲存體系抽象成為一個有用的模型並將管理這個抽象模型 作業系統中管理分層儲存體系的部分稱為儲存管理器。它的任務是有效的管理記憶體,即記錄哪些記憶體是正在使用的,哪些記憶體是空閒的,在程序需要時為其分配記憶體,在程序使用完成的時候為其釋放記憶體。 3.1 無儲存器的

暫存器(記憶體訪問)

記憶體中字的儲存 在cpu中,用16位來儲存一個字,高8位存放高位元組,低8位存放低位位元組。在記憶體中時,由於記憶體單元是位元組單元,剛一個字要用2個地址連續的記憶體單元來存放,字的低位位元組存在低地址單元。 字單元--存放一個字型資料(16位)的記憶體單元,由兩個地址連續的記憶體單元組成,高地址記憶體

《Java併發程式設計實踐——(共享物件)》

共享物件## 編寫正確的併發程式的關鍵在於對共享的、可變的物件狀態進行訪問管理。 上一章使用同步來避免多個執行緒在同一時間訪問同一資料。 同步還有另外的方面:記憶體可見性。 3.1 可見性 public class NoVisibility { private static

jvm_垃圾收集與記憶體分配策略

1:回收哪些記憶體: 程式計數器,虛擬機器棧,本地方法棧屬於執行緒私有,隨執行緒而生,隨執行緒而滅,所以主要考慮方法區和堆記憶體的回收:2 2:哪些物件可以被回收:   引用計數演算法:   可達性分析演算法:GCRoots包括:                   虛擬機器棧中的引用的物件;