最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解讀Jvm的內(nèi)存結(jié)構(gòu)與GC及jvm參數(shù)調(diào)優(yōu)

 更新時間:2023年05月05日 10:05:35   作者:兮家小二  
這篇文章主要介紹了解讀Jvm的內(nèi)存結(jié)構(gòu)與GC及jvm參數(shù)調(diào)優(yōu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、JVM 內(nèi)存結(jié)構(gòu)

1、對象主要存放在堆內(nèi)存中;方法和屬性主要存放在棧內(nèi)存中。

2、棧是運行時單位,用來解決程序運行時的問題,堆是存儲單位,解決數(shù)據(jù)存儲的問題。

3、堆伴隨著JVM的啟動而創(chuàng)建。 

結(jié)構(gòu)圖

1、類加載子系統(tǒng)

負責從文件系統(tǒng)或者網(wǎng)絡(luò)加載Class信息,加載的信息存放在一塊稱之方法區(qū)的內(nèi)存空間。 

2、方法區(qū)(method)

存放類、常量、常量池信息、包括字符串字面量和數(shù)字常量等, 只要是 static 關(guān)鍵字修飾的都在方法區(qū)。

方法區(qū)的數(shù)據(jù)是所有線程共享的。 

3、堆(heap)

幾乎所有的對象實例都存放到Java堆中,堆空間是所有線程共享,比如new 出來的對象。

在堆中的分配的內(nèi)存,由java虛擬機自動垃圾回收器來管理。

其中堆又分為了新生代老年代永久代 (jdk 1.8后取消永久代增加元空間)。

優(yōu)點:是可以動態(tài)地分配內(nèi)存大小,垃圾收集器會自動收走這些不再使用的數(shù)據(jù)。

缺點:由于要在運行時動態(tài)分配內(nèi)存,存取速度較慢

4、棧(stack)

在多線程環(huán)境下,每個線程擁有一個棧和一個程序計數(shù)器,是線程私有的資源。

方法和屬性主要存放在棧內(nèi)存中。

java中的所有引用都在棧中,并指向堆。

引用是創(chuàng)建對象的時候創(chuàng)建的(new ),第二次創(chuàng)建發(fā)現(xiàn)棧中如果有該對象的引用就使用原引用,不會新建

優(yōu)點:存取速度比堆要快,僅次于直接位于CPU中的寄存器,

缺點:存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性,生存期就是他與對象的關(guān)聯(lián)的時間

5、本地方法棧

用于本地方法調(diào)用。Java虛擬機允許Java直接調(diào)用本地方法(通過使用C語言寫) 

6、pc寄存器(了解即可)

PC(Program Couneter)寄存器也是每個線程私有的空間,

Java虛擬機會為每個線程創(chuàng)建PC寄存器,在任意時刻,

一個Java線程總是在執(zhí)行一個方法,這個方法稱為當前方法,

如果當前方法不是本地方法,PC寄存器總會執(zhí)行當前正在被執(zhí)行的指令,

如果是本地方法,則PC寄存器值為Underfined,

寄存器存放如果當前執(zhí)行環(huán)境指針、程序技術(shù)器、操作棧指針、計算的變量指針等信息。 

7、執(zhí)行引擎

虛擬機核心的組件就是執(zhí)行引擎,它負責執(zhí)行虛擬機的字節(jié)碼,一般戶先進行編譯成機器碼后執(zhí)行。 

8、垃圾收集器

垃圾收集系統(tǒng)是Java的核心,也是不可少的,Java有一套自己進行垃圾清理的機制,開發(fā)人員無需手工清理

二、堆–> 新生代/新生代/永久代

1、新生代

主要是用來存放新生的對象。一般占據(jù)堆的1/3空間。

由于頻繁創(chuàng)建對象,所以新生代會頻繁觸發(fā)MinorGC進行垃圾回收。

新生代又分為 Eden區(qū)、ServivorFrom、ServivorTo三個區(qū)。

Eden :Java新對象的出生地(如果新創(chuàng)建的對象占用內(nèi)存很大,則直接分配到老年代)。當Eden區(qū)內(nèi)存不夠的時候就會觸發(fā)MinorGC,對新生代區(qū)進行一次垃圾回收

ServivorTo :保留了一次MinorGC過程中的幸存者。

ServivorFrom :上一次GC的幸存者,作為這一次GC的被掃描者。

MinorGC 是采用復制算法來清理垃圾

2、老年代

主要是用來存放頻繁使用的對象。一般占據(jù)堆的2/3空間。

老年代的對象比較穩(wěn)定,所以MajorGC不會頻繁執(zhí)行。

在進行MajorGC前一般都先進行了一次MinorGC,使得有新生代的對象晉身入老年代,導致空間不夠用時才觸發(fā)。

當無法找到足夠大的連續(xù)空間分配給新創(chuàng)建的較大對象時也會提前觸發(fā)一次MajorGC進行垃圾回收騰出空間。

MajorGC 是采用標記清除算法來清理垃圾

2.1、永久代(jdk1.7前)

指內(nèi)存的永久保存區(qū)域,主要存放Class和Meta(元數(shù)據(jù))的信息,

Class在被加載的時候被放入永久區(qū)域. 它和存放實例的區(qū)域不同

GC不會在主程序運行期對永久區(qū)域進行清理,

永久代的區(qū)域會隨著加載的Class的增多而脹滿,最終拋出OOM異常。

在Java8中,永久代已經(jīng)被移除,被一個稱為“元數(shù)據(jù)區(qū)”(元空間)的區(qū)域所取代。

2.2、元空間(jdk1.8后)

元空間的本質(zhì)和永久代類似,都是對JVM規(guī)范中方法區(qū)的實現(xiàn)。

不過元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機中,而是使用本地內(nèi)存。

默認情況下,元空間的大小僅受本地內(nèi)存限制。

類的元數(shù)據(jù)放入 native memory, 字符串池和類的靜態(tài)變量放入java堆中. 這樣可以加載多少類的元數(shù)據(jù)就不再由MaxPermSize控制, 而由系統(tǒng)的實際可用空間來控制.

三、垃圾回收算法

垃圾回收機制采用算法一覽圖

1、引用算法

使用于新生代,新創(chuàng)建的對象,默認引用值為15

當引用值為 0時,該對象被垃圾回收機制回收

如果有地方引用,可達狀態(tài),則加1, 如果沒有地方引用,不可達狀態(tài),則減1

引用說明,new對象的時候創(chuàng)建,在棧中,并指向堆中的對象

2、復制算法(MinorGC)

使用于新生代ds0,ds1中,引用算法的引用值到達了一定高度次數(shù),就會晉升到ds0,ds1中

新的頻繁使用的對象都會在一個區(qū)內(nèi),要么在ds0,要么在ds1,每次只會有一個區(qū)會有數(shù)據(jù)

假如現(xiàn)在數(shù)據(jù)在ds0中,如果ds0有存活的對象,把存活的對象賦值到ds1,然后清空ds0,新的頻繁使用對象也會晉升在ds1,假如現(xiàn)在數(shù)據(jù)在ds1中,則反之

3、 標記清除算法(MajorGC)

標記清除算法

首先掃描一次所有老年代,標記出存活的對象,然后回收沒有標記的對象。

- MajorGC的耗時比較長,因為要掃描再回收。

- MajorGC會產(chǎn)生內(nèi)存碎片,為了減少內(nèi)存損耗,我們一般需要進行合并或者標記出來方便下次直接分配。----------- 當老年代也滿了裝不下的時候,就會拋出OOM(Out of Memory)異常。

- 標記壓縮法在標記清除基礎(chǔ)之上做了優(yōu)化,把存活的對象壓縮到內(nèi)存一端,而后進行垃圾清理。(java中老年代使用的就是標記壓縮法)

4、 java 手動回收GC

----Java技術(shù)使用finalize()方法在垃圾收集器將對象從內(nèi)存中清除出去前,做必要的清理工作

----把對象賦值為null 在 System.gc(); 即可回收,但不保證100%

public class JVMDemo {
	public static void main(String[] args) {
	    // 創(chuàng)建了堆內(nèi)存
		JVMDemo05 jvmDemo05 = new JVMDemo05();
		// 賦值為空后去除該對象的引用
		//jvmDemo05 = null;
		//手動垃圾回收,只有所有線程都無引用的對象才會會GC回收
		System.gc();
	}
   /**
   * obj 方法,垃圾回收前觸發(fā)
   */
	protected void finalize() throws Throwable {
       System.out.println("gc在回收對象...");
	}
}

四、JVM 參數(shù)調(diào)優(yōu)

堆的常用配置參數(shù)參考

  • -XX:+PrintGC 每次觸發(fā)GC的時候打印相關(guān)日志
  • -XX:+UseSerialGC 串行回收
  • -XX:+PrintGCDetails 更詳細的GC日志
  • -Xms 堆初始值
  • -Xmx 堆最大可用值
  • -Xmn 新生代堆最大可用值
  • -XX:SurvivorRatio 用來設(shè)置新生代中eden空間和from/to空間的比例.含以-XX:SurvivorRatio=eden/from=den/to

圖文方式

1、設(shè)置最大堆內(nèi)存

----- 1、堆內(nèi)存默認大小4G,我們可以根據(jù)程序大小來指定,默認內(nèi)存足夠的情況下不會觸發(fā)垃圾回收機制

----- 2、初始的堆大小與最大堆大小設(shè)置為相等,減少垃圾回收次數(shù),如果內(nèi)存一旦達到初始值,就會觸發(fā)垃圾回收機制,頻繁的觸發(fā)垃圾回收機制影響線程及性能問題

參數(shù):

  • -Xms 堆初始值
  • -Xmx 堆最大可用值
 -Xms512m -Xmx512m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags

2、設(shè)置新生代與老年代優(yōu)化參數(shù)

  • -Xms 堆初始值
  • -Xmx 堆最大可用值
  • -Xmn 新生代大小,一般設(shè)為整個堆的1/3到1/4左右
  • -XX:SurvivorRatio 設(shè)置新生代中eden區(qū)和from/to空間的比例關(guān)系n/1

參數(shù):

-Xms512m -Xmx512m -Xmn170m -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+UseSerialGC

3、堆內(nèi)存溢出處理

錯誤原因

java.lang.OutOfMemoryError Java heap space 堆內(nèi)存溢出

解決辦法

設(shè)置堆內(nèi)存大小,根據(jù)實際大小設(shè)置

  • -Xms 堆初始值
  • -Xmx 堆最大可用值
  • -XX:+HeapDumpOnOutOfMemoryError 內(nèi)存溢出拋出儲存快照

示例:

-Xms512m –Xmx512m -XX:+HeapDumpOnOutOfMemoryError

4、棧內(nèi)存溢出處理

錯誤原因

棧溢出 產(chǎn)生于遞歸調(diào)用,循環(huán)遍歷是不會的,但是循環(huán)方法里面產(chǎn)生遞歸調(diào)用, 也會發(fā)生棧溢出。

java.lang.StackOverflowError 棧內(nèi)存溢出

解決辦法

設(shè)置線程最大調(diào)用深度

-Xss5m      設(shè)置最大調(diào)用深度,默認為1M大小
 示例:
-Xms512m –Xmx512m -Xss5m -XX:+HeapDumpOnOutOfMemoryError

5、Tomcat內(nèi)存溢出

在catalina.sh 修改JVM堆內(nèi)存大小

JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m"

五、 JVM 參數(shù)調(diào)優(yōu)二( GC- 垃圾回收器)

1、串行回收(Serial Collector)

------ 單線程執(zhí)行回收操作,回收期間暫停所有應用線程的執(zhí)行,client模式下的默認回收器,

jvm參數(shù)

-XX:+UseSerialGC      設(shè)置為串行回收

詳細參數(shù)

-XX:+PrintGCDetails -Xmx512M -Xms512M
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseSerialGC
-XX:PermSize=32M

2、并行回收(ParallelGC)

------ ParNew (新生代 )并行回收器在串行回收器基礎(chǔ)上做了改進,他可以使用多個線程同時進行垃圾回收,對于計算能力強的計算機而言,可以有效的縮短垃圾回收所需的實際時間。

------ ParallelOldGC (老年代) 回收器也是一種多線程的回收器,和新生代的ParallelGC回收器一樣,也是一種關(guān)往吞吐量的回收器,他使用了標記壓縮算法進行實現(xiàn)。

jvm參數(shù)

----ParNew設(shè)置(新生代)
XX:+UseParNewGC          設(shè)置為并行回收
XX:ParaleiGCThreads      設(shè)置ParNew回收器工作時的線程數(shù)量,建議指定為電腦核數(shù)*2
----ParallelOldGC設(shè)置(老年代)
-XX:+UseParallelOldGC     設(shè)置為并行回收
-XX:+ParallelCThread      設(shè)置垃圾收集時的線程教量, 建議指定為電腦核數(shù)*2

詳細參數(shù)(UseParNewGC)

-XX:+PrintGCDetails -Xmx512M –Xms512M
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseParNewGC
-XX:PermSize=32M

詳細參數(shù)(UseParallelGC)

-XX:+PrintGCDetails -Xmx512M -Xms256M
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseParallelGC
-XX:+UseParallelOldGC
-XX:ParallelGCThreads=8
-XX:PermSize=32M

G1回收器了解

G1回收器(Garbage-First)實在]dk1.7中提出的垃圾回收器,從長期目標來看是為了取代CMS回收器,G1回收器擁有獨特的垃圾回收策略,G1屬于分代垃圾回收器,區(qū)分新生代和老年代,依然有eden和from/to區(qū),它并不要求整個eden區(qū)或者新生代、老年代的空間都連續(xù),它使用了分區(qū)算法。

jvm調(diào)優(yōu)總結(jié)

1、初始堆值和最大堆內(nèi)存內(nèi)存越大,吞吐量就越高。

2、最好使用并行收集器,因為并行手機器速度比串行吞吐量高,速度快。

3、設(shè)置堆內(nèi)存新生代的比例和老年代的比例最好為1:2或者1:3。

4、減少GC對老年代的回收。

六、java 代碼中查看大小

public class JvmDemo01 {
	public static void main(String[] args) throws InterruptedException {
		byte[] b1 = new byte[1 * 1024 * 1024];
		System.out.println("分配了1m");
		jvmInfo();		
		Thread.sleep(3000);
		byte[] b2 = new byte[4 * 1024 * 1024];
		System.out.println("分配了4m");
		Thread.sleep(3000);
		jvmInfo();
	}
	static private String toM(long maxMemory) {
		float num = (float) maxMemory / (1024 * 1024);
		DecimalFormat df = new DecimalFormat("0.00");// 格式化小數(shù)
		String s = df.format(num);// 返回的是String類型
		return s;
	}
	static private void jvmInfo() {
		// 最大內(nèi)存
		long maxMemory = Runtime.getRuntime().maxMemory();
		System.out.println("maxMemory:" + maxMemory + ",轉(zhuǎn)換為M:" + toM(maxMemory));
		// 當前空閑內(nèi)存
		long freeMemory = Runtime.getRuntime().freeMemory();
		System.out.println("freeMemory:" +freeMemory+",轉(zhuǎn)換為M:"+toM(freeMemory));
		// 已經(jīng)使用內(nèi)存
		long totalMemory = Runtime.getRuntime().totalMemory();
		System.out.println("totalMemory:" +totalMemory+",轉(zhuǎn)換為M"+toM(totalMemory));
	}
}

idea 設(shè)置參數(shù)

進入編輯找到對應的啟動類,VM哪填寫JVM參數(shù)就好了

eclipse 設(shè)置參數(shù)

設(shè)置

啟動jar 項目設(shè)置參數(shù)

java -jar -Xms20m -Xmx20m xxxxx.jar

其他:壓力測試工具 JMeter,可測試接口吞吐量(每秒的并發(fā)量)

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決@CachePut設(shè)置的key值無法與@CacheValue的值匹配問題

    解決@CachePut設(shè)置的key值無法與@CacheValue的值匹配問題

    這篇文章主要介紹了解決@CachePut設(shè)置的key的值無法與@CacheValue的值匹配問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 一文解決System.in關(guān)閉后無法再繼續(xù)使用流的問題

    一文解決System.in關(guān)閉后無法再繼續(xù)使用流的問題

    這篇文章主要給大家介紹如何解決System.in關(guān)閉后無法再繼續(xù)使用流的問題,文中有詳細的解決方法和代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-07-07
  • Mybatis之foreach標簽內(nèi)傳入list為空的問題

    Mybatis之foreach標簽內(nèi)傳入list為空的問題

    這篇文章主要介紹了Mybatis之foreach標簽內(nèi)傳入list為空的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Java中實現(xiàn)定時任務的兩種方法舉例詳解

    Java中實現(xiàn)定時任務的兩種方法舉例詳解

    這篇文章主要給大家介紹了關(guān)于Java中實現(xiàn)定時任務的兩種方法,文中總結(jié)了各種實現(xiàn)方式的優(yōu)缺點,并給出了推薦的使用場景,通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12
  • 使用java批量寫入環(huán)境變量的實現(xiàn)

    使用java批量寫入環(huán)境變量的實現(xiàn)

    本文主要介紹了使用java批量寫入環(huán)境變量,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-03-03
  • 淺談解決Hibernate懶加載的4種方式

    淺談解決Hibernate懶加載的4種方式

    這篇文章主要介紹了淺談解決Hibernate懶加載的4種方式,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • 三行Java代碼實現(xiàn)計算多邊形的幾何中心點

    三行Java代碼實現(xiàn)計算多邊形的幾何中心點

    因為工作需要計算采煤機工作面的中心點,如果套用數(shù)學的計算公式,用java去實現(xiàn),太麻煩了。本文將利用java幾何計算的工具包,幾行代碼就能求出多變形的中心,簡直yyds!還不快跟隨小編一起學起來
    2022-10-10
  • SpringBoot使用Nacos進行application.yml配置管理

    SpringBoot使用Nacos進行application.yml配置管理

    Nacos是阿里巴巴開源的一個微服務配置管理和服務發(fā)現(xiàn)的解決方案,它提供了動態(tài)服務發(fā)現(xiàn)、配置管理和?服務管理平臺,Nacos使用Raft協(xié)議保證配置的一致性,同時支持多種配置?格式,如properties、yaml等,本文介紹了SpringBoot使用Nacos進行application.yml配置管理
    2024-12-12
  • 源碼分析SpringMvc日志打印被忽略輸出問題

    源碼分析SpringMvc日志打印被忽略輸出問題

    這篇文章主要為大家介紹了源碼分析SpringMvc日志打印被忽略輸出問題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 淺談java實現(xiàn)背包算法(0-1背包問題)

    淺談java實現(xiàn)背包算法(0-1背包問題)

    本篇文章主要介紹了淺談java實現(xiàn)背包算法(0-1背包問題) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08

最新評論

锦屏县| 威海市| 庆城县| 太仓市| 涟水县| 淳安县| 富裕县| 洪洞县| 忻州市| 杂多县| 平罗县| 文山县| 绵阳市| 清远市| 济南市| 镶黄旗| 宝坻区| 疏附县| 乌鲁木齐县| 离岛区| 伊吾县| 成都市| 珲春市| 南宫市| 娄底市| 东莞市| 隆尧县| 罗山县| 精河县| 永川市| 长岛县| 乌兰浩特市| 如皋市| 天全县| 出国| 淅川县| 沧州市| 兴城市| 保康县| 富源县| 牙克石市|