六、JVM之垃圾回收

来源:https://www.cnblogs.com/lee0527/archive/2020/01/21/12221383.html
-Advertisement-
Play Games

GC日誌 Heap PSYoungGen total 305664K, used 26214K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000) eden space 262144K, 10% used [0x00000000e ...


GC日誌

-Xmx1024m -Xms1024m -XX:+PrintGCDetails

Heap
PSYoungGen total 305664K, used 26214K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000)
eden space 262144K, 10% used [0x00000000eab00000,0x00000000ec499be8,0x00000000fab00000)
from space 43520K, 0% used [0x00000000fd580000,0x00000000fd580000,0x0000000100000000)
to space 43520K, 0% used [0x00000000fab00000,0x00000000fab00000,0x00000000fd580000)
ParOldGen total 699392K, used 0K [0x00000000c0000000, 0x00000000eab00000, 0x00000000eab00000)
object space 699392K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000eab00000)
Metaspace used 3224K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 351K, capacity 388K, committed 512K, reserved 1048576K

下麵再編寫一個代碼,觀察GC的觸發操作

public class Demo {
    public static void main(String[] args){
        Random random = new Random();
        String  val = "test";
        while (true){
            val+=val+random.nextInt(999999999)+random.nextInt(999999999);
        }
    }
}

[GC (Allocation Failure) [PSYoungGen: 2031K->488K(2560K)] 2031K->676K(9728K), 0.0013870 secs] [Times: user=0.06 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2441K->504K(2560K)] 2629K->1254K(9728K), 0.0010120 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 1950K->488K(2560K)] 2700K->1951K(9728K), 0.0011297 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 1940K->488K(2560K)] 4796K->4049K(9728K), 0.0012419 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 1257K->488K(2560K)] 6212K->5443K(9728K), 0.0009412 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 488K->496K(1536K)] 5443K->5491K(8704K), 0.0005513 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 496K->0K(1536K)] [ParOldGen: 4995K->2727K(7168K)] 5491K->2727K(8704K), [Metaspace: 3281K->3281K(1056768K)], 0.0066911 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 30K->32K(2048K)] 6938K->6940K(9216K), 0.0004666 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 32K->0K(2048K)] [ParOldGen: 6908K->2030K(7168K)] 6940K->2030K(9216K), [Metaspace: 3281K->3281K(1056768K)], 0.0082892 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 19K->0K(2048K)] 6231K->6211K(9216K), 0.0003457 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 6211K->4817K(7168K)] 6211K->4817K(9216K), [Metaspace: 3281K->3281K(1056768K)], 0.0027242 secs] [Times: user=0.08 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] 4817K->4817K(9216K), 0.0003852 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 4817K->4798K(7168K)] 4817K->4798K(9216K), [Metaspace: 3281K->3281K(1056768K)], 0.0095410 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

GC日誌分析

JVM垃圾回收

垃圾對象判定標準

jvm的GC工作主要針對的對象是堆記憶體,在做GC工作之前,首先要判定堆記憶體中的對象實例是否為垃圾,通常使用以下兩種演算法來定義

1.引用計數演算法

java在運行時,當有一個地方引用該對象實例,會將這個對象實例加1,引用失效時就減1,jvm在掃描記憶體時,發現引用計數值為0的則是垃圾對象,計數值大於0的則為活躍對象。

目前垃圾回收演算法,沒有採用引用計數演算法,原因是在對象互相引用的情況下,無法判定兩者是否為垃圾對象。

2. 根搜索演算法

根搜索演算法是以“GC ROOTS”為起始點往下搜索,所有經過的對象合併起來稱為引用鏈,在這引用鏈里,沒有的對象稱為垃圾對象,在引用鏈里的是活躍對象。那什麼樣的對象才能稱為“GC ROOTS”呢?以下四種可以

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

垃圾回收演算法

1. 標記-清除(Mark-Sweep)

jvm會掃描所有的對象實例,通過根搜索演算法,將活躍對象進行標記,jvm再一次掃描所有對象,將未標記的對象進行清除,只有清除動作,不作任何的處理,這樣導致的結果會存在很多的記憶體碎片。

2. 複製(copying)

jvm掃描所有對象,通過根搜索演算法標記被引用的對象,之後會申請新的記憶體空間,將標記的對象複製到新的記憶體空間里,存活的對象複製完,會清空原來的記憶體空間,將新的記憶體最為jvm的對象存儲空間。這樣雖然解決了記憶體記憶體碎片問題,但是如果對象很多,重新申請新的記憶體空間會很大,在記憶體不足的場景下,會對jvm運行造成很大的影響

3. 標記-整理(Mark-compact)

標記整理實際上是在標記清除演算法上的優化,執行完標記清除全過程之後,再一次對記憶體進行整理,將所有存活對象統一向一端移動,這樣解決了記憶體碎片問題。

4. 分代回收

目前jvm常用回收演算法就是分代回收,年輕代以複製演算法為主,老年代以標記整理演算法為主。原因是年輕代對象比較多,每次垃圾回收都有很多的垃圾對象回收,而且要儘可能快的減少生命周期短的對象,存活的對象較少,這時候複製演算法比較適合,只要將有標記的對象複製到另一個記憶體區域,其餘全部清除,並且複製的數量較少,效率較高;而老年代是年輕代篩選出來的對象,被標記比較多,需要刪除的對象比較少,顯然採用標記整理效率較高。


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

-Advertisement-
Play Games
更多相關文章
  • 本文提供數百個電腦畢設題目可以參考 並提供成品源碼下載,都是從網上收集而來 源碼技術全部採用java+MySQL開發,並結合了其他技術如ssm,ssh,jsp等等。 下載鏈接在文末! 以下是項目名稱目錄: jd 1-CRM客戶關係管理系統-ssh2-戶籍管理系統-jsp3-Java聊天室的設計與實 ...
  • 一、關於Integer中常用的方法 package com.bjpowernode.java_learning; ​ public class D77_1_ { public static void main(String[] args) { Integer i1 = new Integer(10) ...
  • 開發環境: Windows操作系統 開發工具: MyEclipse+Jdk+Tomcat+MySql資料庫 職工管理系統作為一種管理軟體正在各公司中得到越來越廣泛的應用,且已達到了良好效果。 運行效果圖: 源碼及原文鏈接:http://javadao.xyz/forum.php?mod=viewth ...
  • 我看的這本是Bjarne Stroustrup寫的,南開大學的楊巨峰和王剛譯的。這本書不適合初學者看,我就是大概翻了翻其中感興趣的章節。 這本書第14章的標題是“歷史和相容性”,這節內容我看了收穫很深。p144-145的內容值得去看。 從中可以看出,ISO C和ISO C++是K&R C [Kern ...
  • 這次是關於spring的面試題,和上次一樣依舊挑了幾個具有代表性的。 一. 談談你對 Spring 的理解 Spring 是一個開源框架,為簡化企業級應用開發而生。Spring 可以是使簡單的 JavaBean 實現以前只有 EJB 才能實現的功能。Spring 是一個 IOC 和 AOP 容器框架 ...
  • YAML 是 "YAML Ain't a Markup Language"(YAML 不是一種標記語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思其實是:"Yet Another Markup Language"(仍是一種標記語言)。 YAML 的語法和其他高級語言類似,並且可以簡單表達清單、 ...
  • 原文地址: "http://www.work100.net/training/java if else.html" 更多教程: "光束雲 免費課程" 條件語句 序號|文內章節|視頻 : :|: |: 1| "概述" | 2| "if...else語句" | 3| "if...else...if... ...
  • 當我開始使用Flutter實施該應用程式時,我開始擔心“如何最好地編寫?”以及“如何使其更好地放置?”。 在這種情況下,您將需要參考GitHub上發佈的代碼和應用程​​序。 因此,我收集了似乎對Flutter 應用程式開發有用的代碼/庫/專有技術。 Flutter公式:編寫您的第一個Flutter應 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...