<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java內(nèi)存模型(JMM)【垃圾回收相關(guān)】

          共 4755字,需瀏覽 10分鐘

           ·

          2021-06-01 23:45

          點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時間送達(dá)

          結(jié)合幾個面試題來學(xué)習(xí)

          1、簡單講一下Java的內(nèi)存模型?

          2、Java 的 GC機制

          • GC有多少種垃圾回收的算法?

          • 你聽說過 年輕代、老年代嗎?

          • 復(fù)制算法、標(biāo)記清除 有了解過嗎?

          3、Java內(nèi)存管理:常見的變量,在內(nèi)存的不同區(qū)域,GC的回收;

          • 我在new一個對象的時候,它是被放在內(nèi)存的那一塊區(qū)域;

          • 成員變量和局部變量:在內(nèi)存區(qū)域位置的區(qū)別和回收方面的區(qū)別;

          相關(guān)資料

          相關(guān)文章:Java虛擬機 平行系列二

          1、Java內(nèi)存模型

          1.1、JVM整體介紹:

          java(javac)--> class文件(JVM把class文件翻譯成機器碼) --> Linux、Windows等平臺(只認(rèn)識機器碼101010)。

          JVM可以理解為一個翻譯,把class文件翻譯成機器碼,所以JVM具有跨平臺性。

          1.2、運行時數(shù)據(jù)區(qū):

          1.3、Java內(nèi)存模型

          內(nèi)存模型設(shè)計:由兩個部分的數(shù)據(jù)非常關(guān)鍵,堆內(nèi)存和方法區(qū),因為這兩個區(qū)域的存放的是所有線程共享的數(shù)據(jù),因此數(shù)據(jù)會比較多。而線程私有的數(shù)據(jù)區(qū)如程序計數(shù)器,本地方法棧、虛擬機棧里面的數(shù)據(jù)跟線程的生命周期有關(guān),一旦線程被銷毀,這些數(shù)據(jù)也就被回收了,因此不用過多關(guān)注。

          2、垃圾回收算法

          2.1、如何判斷某個對象是否是垃圾?

          https://www.cnblogs.com/dolphin0520/p/3783345.html

          我們先來了解一個最基本的問題:如果確定某個對象是“垃圾”?既然垃圾收集器的任務(wù)是回收垃圾對象所占的空間供新的對象使用,那么垃圾收集器如何確定某個對象是“垃圾”?———即通過什么方法判斷一個對象可以被回收了。

          public class Main {
              public static void main(String[] args) {
                  MyObject object1 = new MyObject();
                  MyObject object2 = new MyObject();
                   
                  object1.object = object2;
                  object2.object = object1;
                   
                  object1 = null;
                  object2 = null;
              }
          }
           
          class MyObject{
              public Object object = null;
          }

          最后面兩句將object1和object2賦值為null,也就是說object1和object2指向的對象已經(jīng)不可能再被訪問,但是由于它們互相引用對方,導(dǎo)致它們的引用計數(shù)都不為0,那么垃圾收集器就永遠(yuǎn)不會回收它們。

            為了解決這個問題,在Java中采取了 可達(dá)性分析法。該方法的基本思想是通過一系列的“GC Roots”對象作為起點進行搜索,如果在“GC Roots”和一個對象之間沒有可達(dá)路徑,則稱該對象是不可達(dá)的,不過要注意的是被判定為不可達(dá)的對象不一定就會成為可回收對象。被判定為不可達(dá)的對象要成為可回收對象必須至少經(jīng)歷兩次標(biāo)記過程,如果在這兩次標(biāo)記過程中仍然沒有逃脫成為可回收對象的可能性,則基本上就真的成為可回收對象了。

          Java垃圾回收-可達(dá)性分析算法

          也可以看:深入理解Java虛擬機:JVM高級特性與最佳實踐(第3版) 周志明  3.2章節(jié)

          回收算法有3種:

          2.2、標(biāo)記-清除

          通過可達(dá)性分析的方式來標(biāo)記需要回收的對象。

          清除后:

          缺點:

          1. 堆中所有的對象都會被掃描一遍,從而才能確定需要回收的對象,比較耗時

          2. 有空間碎片,空間不連續(xù),導(dǎo)致一些打的對象可能分配不到合適的空間,這樣就還會觸發(fā)GC回收,而GC回收是比較耗時的

          2.3、標(biāo)記-復(fù)制

          清除后:

          優(yōu)點:不會有空間碎片;

          缺點:浪費了一半的空間;

          2.4、標(biāo)記-整理

          整理后:

          堆:Old  Young(Eden、S0和S1)
          哪個算法用在哪個區(qū)域呢?
          不同的代用不同的垃圾回收算法

          Young區(qū),復(fù)制 ---> 前提條件:每次垃圾回收 存活的對象都比較少  ---> 復(fù)制算法
                  絕大多數(shù)的對象都被回收掉了  --->  一般的對象都是朝生夕死的

          垃圾回收的過程,GC日志  文章名:Understanding G1 GC Logs  https://blogs.oracle.com/poonam/understanding-g1-gc-logs

          結(jié)論:Young區(qū)使用復(fù)制算法是沒有問題的。

          Old區(qū):一般是存活時間比較長的,意味著很難被回收 ---> 
                  當(dāng)需要要回收的對象很少時,使用標(biāo)記整理算法(只標(biāo)記,不清除);
                  當(dāng)需要回收的對象很多時,使用標(biāo)記清除算法;

          總結(jié):

          • 1、新生代: 新生代中的對象存活率低,只要付出少量的復(fù)制成本就能完成回收過程,因此選用復(fù)制算法;

          • 2、老生代: 老生代中的對象存活率高,并且沒有額外空間進行分配擔(dān)保,因此選用 “標(biāo)記 - 清理” 或 “標(biāo)記 - 整理” 算法。

          3、面試題

          1、簡單講一下Java的內(nèi)存模型?

          2、Java 的 GC機制

          • GC有多少種垃圾回收的算法?

          • 你聽說過 年輕代、老年代嗎?

          • 復(fù)制算法、標(biāo)記清除 有了解過嗎?

          3、Java內(nèi)存管理:常見的變量,在內(nèi)存的不同區(qū)域,GC的回收;

          • 我在new一個對象的時候,它是被放在內(nèi)存的那一塊區(qū)域;

          • 成員變量和局部變量:在內(nèi)存區(qū)域位置的區(qū)別和回收方面的區(qū)別;

          3.1、簡單講一下Java內(nèi)存模型【垃圾回收相關(guān)】。

          JVM的運行時數(shù)據(jù)區(qū)包括線程私有(程序計數(shù)器、本地方法棧、虛擬機棧)和線程共享(堆、方法區(qū))。

          而內(nèi)存模型的設(shè)計主要考慮線程共享區(qū)域,因為這兩個區(qū)域存放的是所有線程共享的數(shù)據(jù),因此數(shù)據(jù)會比較多,而線程私有的數(shù)據(jù)跟線程的生命周期有關(guān),一旦線程被銷毀,這些數(shù)據(jù)也就被回收了,因此不用過多關(guān)注。

          而線程共享區(qū)域包含有堆和方法區(qū),方法區(qū)也不用關(guān)注,因為方法區(qū)里面的內(nèi)存分配和垃圾回收我們無法控制,那么我們只有一個區(qū)域需要關(guān)注了,那就是堆。 

          堆可分為老年代和新生代,新生代又分為Eden空間、From Survivor空間、To Survivor空間。(空間比例為8:1:1)。

          3.2、簡單講一下新生代和老年代。

          https://blog.csdn.net/jisuanjiguoba/article/details/80156781

          堆可分為老年代和新生代,新生代又分為Eden空間、From Survivor空間、To Survivor空間。(空間比例為8:1:1)。

           1)年輕代(Young Gen):年輕代主要存放新創(chuàng)建的對象,內(nèi)存大小相對會比較小,垃圾回收會比較頻繁。年輕代分成1個Eden Space和2個Suvivor Space(命名為A和B)。當(dāng)對象在堆創(chuàng)建時,將進入年輕代的Eden Space。垃圾回收器進行垃圾回收時,掃描Eden Space和A Suvivor Space,如果對象仍然存活,則復(fù)制到B Suvivor Space,如果B Suvivor Space已經(jīng)滿,則復(fù)制到Old Gen。同時,在掃描Suvivor Space時,如果對象已經(jīng)經(jīng)過了幾次的掃描仍然存活,JVM認(rèn)為其為一個持久化對象,則將其移到Old Gen。掃描完畢后,JVM將Eden Space和A Suvivor Space清空,然后交換A和B的角色(即下次垃圾回收時會掃描Eden Space和B Suvivor Space。這么做主要是為了減少內(nèi)存碎片的產(chǎn)生。

          我們可以看到:Young Gen垃圾回收時,采用將存活對象復(fù)制到到空的Suvivor Space的方式來確保盡量不存在內(nèi)存碎片,采用空間換時間的方式來加速內(nèi)存中不再被持有的對象盡快能夠得到回收。

          2)年老代(Tenured Gen):年老代主要存放JVM認(rèn)為生命周期比較長的對象(經(jīng)過幾次的Young Gen的垃圾回收后仍然存在),內(nèi)存大小相對會比較大,垃圾回收也相對沒有那么頻繁(譬如可能幾個小時一次)。年老代主要采用壓縮的方式來避免內(nèi)存碎片(將存活對象移動到內(nèi)存片的一邊,也就是內(nèi)存整理)。當(dāng)然,有些垃圾回收器(譬如CMS垃圾回收器)出于效率的原因,可能會不進行壓縮。

          3)持久代(Perm Gen):持久代主要存放類定義、字節(jié)碼和常量等很少會變更的信息。

          總結(jié):

          • 1、新生代: 新生代中的對象存活率低,只要付出少量的復(fù)制成本就能完成回收過程,因此選用復(fù)制算法;

          • 2、老生代: 老生代中的對象存活率高,并且沒有額外空間進行分配擔(dān)保,因此選用 “標(biāo)記 - 清理” 或 “標(biāo)記 - 整理” 算法。

          3.3、GC有多少種垃圾回收的算法,都是什么?

          3種,見上。

          3.4、我在new一個對象的時候,它是被放在內(nèi)存的那一塊區(qū)域?

          堆。

          3.5、成員變量和局部變量:在內(nèi)存區(qū)域位置的區(qū)別和回收方面的區(qū)別?

          成員變量:放在堆內(nèi)存中,

          局部變量:放在 Java Virtual Machine Stacks(Java虛擬機堆棧),


          版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。

          本文鏈接:

          https://blog.csdn.net/songzi1228/article/details/117173102








          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天操天天摸天天日不卡 | 强欧美小嫩苞第一次免费视频 | 伊人激情综合网 | 麻豆网站-麻豆午夜在线-成人AV | 日韩欧美国产三级片 |