亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 127632 | 回復(fù): 13
打印 上一主題 下一主題

【話題討論+送書福利】如何成為Java大神級程序員?虛擬機的知識你掌握了嗎? [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2021-09-15 13:51 |只看該作者 |倒序瀏覽
本期獲獎名單~盡快私信聯(lián)系我 郵寄地址哦~

3樓    東風玖哥                  @東風玖哥
4樓    校長我錯了               @校長我錯了
5樓     jieforest               @jieforest
6樓       aloki                   @aloki
8樓      fenyun689           @fenyun689





話題背景:


Java是一門流行多年的高級編程語言,與其相關(guān)的就業(yè)崗位很多,但是最近幾年卻出現(xiàn)了用人單位招不到合適的人,而大量Java程序員找不到工作的尷尬局面。究其根本原因是崗位對Java開發(fā)技術(shù)的要求高,不但要會應(yīng)用,而且更要懂其內(nèi)部的運行原理。對于想要深入研究Java技術(shù)的從業(yè)人員來說,虛擬機是繞不開的話題。近期機械工業(yè)出版社出版了《深入剖析Java虛擬機:源碼剖析與實例詳解(基礎(chǔ)卷)》一書,是一本詳細剖析工業(yè)級Java虛擬機HotSpot源碼實現(xiàn)的書籍,是Java開發(fā)者探索Java底層原理,競爭高端職位不可多得的一本好書。本次活動便是以此為契機,和各位Java開發(fā)者就Java虛擬機的相關(guān)話題展開討論,歡迎大家踴躍發(fā)言。


本次話題:

(1)請詳細說說你所知道的Java類的生命周期。

(2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?

(3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。

(4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。



本期獎品:

最佳積極參與經(jīng)驗分享獎5名,獎勵價值149元的《深入剖析Java虛擬機:源碼剖析與實例詳解(基礎(chǔ)卷)》圖書1本。

深入剖析Java虛擬機:源碼剖析與實例詳解(基礎(chǔ)卷)
馬智  著
書號:978-7-111-68989-8
印張:32(共512頁)
定價:149.00元
上架建議:計算機/Java



參與方式:

直接在該主題下回帖即可。
活動時間:2021年9月15日-10月15日


圖書購買:

京東:https://item.jd.com/12926187.html
當當:http://product.dangdang.com/29291057.html


圖書試讀: 第1-2章.pdf (1.55 MB, 下載次數(shù): 86) 內(nèi)容簡介 前言 目錄.pdf (462.56 KB, 下載次數(shù): 87)


論壇徽章:
59
2015七夕節(jié)徽章
日期:2015-08-24 11:17:25ChinaUnix專家徽章
日期:2015-07-20 09:19:30每周論壇發(fā)貼之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38榮譽版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年紀念徽章
日期:2015-07-20 11:05:27IT運維版塊每日發(fā)帖之星
日期:2015-07-20 11:05:34操作系統(tǒng)版塊每日發(fā)帖之星
日期:2015-07-20 11:05:36程序設(shè)計版塊每日發(fā)帖之星
日期:2015-07-20 11:05:40數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-07-20 11:05:432015年辭舊歲徽章
日期:2015-07-20 11:05:44
2 [報告]
發(fā)表于 2021-09-15 21:59 |只看該作者
本帖最后由 renxiao2003 于 2021-10-29 09:09 編輯

我這么好的回復(fù)居然沒中。刪除了。呵呵。

論壇徽章:
8
15-16賽季CBA聯(lián)賽之青島
日期:2017-05-25 14:27:3415-16賽季CBA聯(lián)賽之深圳
日期:2017-07-19 09:39:23CU十四周年紀念徽章
日期:2017-08-29 16:08:0115-16賽季CBA聯(lián)賽之佛山
日期:2017-08-30 19:12:5515-16賽季CBA聯(lián)賽之山西
日期:2017-12-20 13:50:5519周年集字徽章-19
日期:2019-09-12 16:11:0719周年集字徽章-慶
日期:2019-09-12 16:13:3215-16賽季CBA聯(lián)賽之北控
日期:2020-04-26 16:30:57
3 [報告]
發(fā)表于 2021-09-17 10:00 |只看該作者
(1)請詳細說說你所知道的Java類的生命周期。
一個java類的完整的生命周期會經(jīng)歷加載、連接、初始化、使用、和卸載五個階段,其中“連接”又可以分為驗證、準備、解析三個小階段

(2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?
Runtime area分區(qū)在不同VM上有明顯的區(qū)別,在一般的Hotspot VM上,每個Thread都有自己的程序計數(shù)器和Stack,然后GC主要發(fā)生在Heap里,class信息和常量池保存在的Heap老生代;而Android的ART VM,每個Thread有自己的程序計數(shù)器和VM Stack以及native Stack,class信息和常量池保存在單獨的method area

(3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。
恰當?shù)卣f,本題就是問GC原理,新創(chuàng)建的對象都要被優(yōu)先分配到新生代,過大的對象會直接加入老生代,新生代采用 標記-復(fù)制 算法,而老生代采用 標記-清除 算法,如果碎片過多,則采用 標記-整理 算法

(4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。
防止頻繁GC,建議采用享元模式復(fù)用對象解決

論壇徽章:
0
4 [報告]
發(fā)表于 2021-09-17 15:22 |只看該作者
(1)請詳細說說你所知道的Java類的生命周期。
  • 加載:class字節(jié)碼文件載入到虛擬機
  • 連接:

    • 驗證一下這個類是否合法
    • 類的靜態(tài)變量分配內(nèi)存并設(shè)為jvm默認的初值

    • 常量池中的符號引用轉(zhuǎn)換為直接引用
  • 初始化:如果一個類被直接引用,就會觸發(fā)類的初始化
  • 使用:
  • 卸載

    • 該類所有的實例都已經(jīng)被回收
  • 加載該類的ClassLoader已經(jīng)被回收
  • 該類對應(yīng)的java.lang.Class對象沒有任何地方被引用
(2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?
  • 元空間、堆、虛擬機棧、本地方法棧和程序計數(shù)器
  • 主要是為了方便垃圾收集器對對象進行管理
(3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。
  • 依據(jù)逃逸分析,如果未逃逸則把對象分配到VM Stack
  • 否則判斷大對象,如果是則直接分配到堆上 Old Generation 老年代上
  • 否則判斷是否可以在 TLAB(線程分配緩沖區(qū))中分配,如果是在 TLAB中分配
  • 否則,在共享的Eden區(qū)分配。
(4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。
  • YGC過于頻繁

    • Young/Eden 區(qū)過小
    • System.gc頻繁調(diào)用
  • YGC的STW過長

    • CPU過高
    • 回收對象過多
  • FGC過于頻繁

    • Young/Eden 區(qū)過小
    • System.gc頻繁調(diào)用

    • 老年代的空間不足
    • 對象晉升年齡過小

    • 大的對象過多
    • 動態(tài)加載的類過多
  • FGC的STW過長

    • 同F(xiàn)GC過于頻繁
    • 內(nèi)存泄漏

論壇徽章:
32
CU大;照
日期:2013-05-20 10:45:13每日論壇發(fā)貼之星
日期:2015-09-07 06:20:00每日論壇發(fā)貼之星
日期:2015-09-07 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-12-13 06:20:0015-16賽季CBA聯(lián)賽之江蘇
日期:2016-03-03 11:56:13IT運維版塊每日發(fā)帖之星
日期:2016-03-06 06:20:00fulanqi
日期:2016-06-17 17:54:25IT運維版塊每日發(fā)帖之星
日期:2016-07-23 06:20:0015-16賽季CBA聯(lián)賽之佛山
日期:2016-08-11 18:06:41JAVA
日期:2016-10-25 16:09:072017金雞報曉
日期:2017-01-10 15:13:292017金雞報曉
日期:2017-02-08 10:33:21
5 [報告]
發(fā)表于 2021-09-19 11:44 |只看該作者
本帖最后由 jieforest 于 2021-09-19 11:48 編輯

1)請詳細說說你所知道的Java類的生命周期。
Java虛擬機為Java程序提供運行時環(huán)境,其中一項重要的任務(wù)就是管理類和對象的生命周期。
一個Java類完整的生命周期通常會經(jīng)歷加載、連接、初始化、使用、和卸載五個階段,也存在加載或者連接之后沒有被初始化就直接被使用的情況,可以用一個圖來表示這個過程:



2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?
JVM虛擬機在運行Java應(yīng)用程序的過程中,會將它管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。《Java虛擬機規(guī)范》這本書中描述了這種劃分規(guī)定,將內(nèi)存區(qū)域劃分為:
1. 程序計數(shù)器(Program Counter Register):一塊比較小的內(nèi)存區(qū)域,可看做是當前線程執(zhí)行字節(jié)碼的行號指示器,以此實現(xiàn)指令的分支、循環(huán)、跳轉(zhuǎn)、異常處理等功能。
2. 虛擬機棧(VM Stack):其棧元素是一種名為棧幀(Stack Frame)的數(shù)據(jù)結(jié)構(gòu),以便支持Java虛擬機進行方法調(diào)用和方法執(zhí)行,當Java方法從開始調(diào)用到執(zhí)行完成時,就對應(yīng)著一個棧幀在虛擬機棧的入棧到出棧的過程。每一個棧幀都包含了:局部變量表(Local Variable Table)、操作數(shù)棧(Operand Stack)、動態(tài)鏈接(Dynamic Linking)、方法返回地址(Return Address),以及一些附加信息。
3. 本地方法棧(Native Method Stack):本地方法棧與虛擬機棧相似,但此區(qū)域用于存儲本地方法的局部變量表、本地方法的操作數(shù)棧等信息。與虛擬機棧最大的不同在于,虛擬機棧執(zhí)行的是Java方法,而本地方法棧執(zhí)行的是原生方法(Native Method),也就是C/C++方法。因為Java是高級編程語言,當訪問底層OS或硬件時,需要通過JNI方式來調(diào)用原生方法來實現(xiàn)。
4. 方法區(qū)(Method Area):此區(qū)域存儲已加載的類信息、常量、靜態(tài)變量、即時編譯后的代碼等數(shù)據(jù)。其中類相關(guān)的信息有類名、訪問修飾符、常量池、字段描述、方法描述等。方法區(qū)在邏輯上屬于堆的一部分,但為了與堆進行區(qū)分,通常又稱為“非堆”。方法區(qū)的數(shù)據(jù)是線程共享的。
5. 堆(Heap):堆是JVM管理的內(nèi)存中最大的一塊內(nèi)存區(qū)域,幾乎所有類/對象實例和數(shù)組的內(nèi)存均從此處分配。之所以說“幾乎”,是因為隨著JIT編譯器的發(fā)展與逃逸分析技術(shù)的逐漸成熟,棧上分配、標量替換優(yōu)化技術(shù)導(dǎo)致了一些分配上的改變。Java堆是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱作為GC堆(Garbage Collected Heap)。由于收集器基本都采用分代收集算法,所以Java堆還可以細分為:新生代和老年代。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可,就像磁盤那樣。
以上五個區(qū)域。

3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。
很不錯的問題,贊一個。
內(nèi)存可分為兩部分:
1. 棧內(nèi)存(stack memory):有更快的訪問效率且為連續(xù)分配
2. 堆內(nèi)存(heap memory):比較慢的訪問效率且為動態(tài)分配
JVM為Java對象分配內(nèi)存是在堆內(nèi)存區(qū)域處理的,而把棧內(nèi)存區(qū)域用作函數(shù)調(diào)用等用途。
在Java語言中,JVM在啟動時負責創(chuàng)建堆內(nèi)存空間,且這個堆內(nèi)存的尺寸是動態(tài)的的,可以根據(jù)程序的需求進行增加或減少。
我們還應(yīng)該注意到Java也在堆外分配內(nèi)存,這可用于:內(nèi)部數(shù)據(jù)結(jié)構(gòu)、方法/函數(shù)的調(diào)用、線程等。
在Java語言中,堆內(nèi)存又分為兩部分:
1. 年輕代(young generation)
2. 老年代(old generation)
在年輕代內(nèi)存空間中,存儲了最近創(chuàng)建的對象;而在老年代內(nèi)存空間中,則存儲長時間使用的對象。這種對象分類是為了更快和更有效的執(zhí)行垃圾收集。
年輕代內(nèi)存空間可進一步劃分為保留區(qū)(keep area),它保留最近創(chuàng)建的對象。哪怕在垃圾收集時創(chuàng)建了大量的對象,也會將這些最近創(chuàng)建的對象存儲到保留區(qū)。
當JVM為Java對象分配內(nèi)存時,JVM會對Java對象進行識別:
1. 這是小對象
2. 這是很大的對象
這取決于對象所需的內(nèi)存尺寸。我們可以使用工具包在Java中獲取任何對象的大小。例如
```java
import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
    private static Instrumentation instrumentation;
    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }
    public static long getObjectSize(Object o) {
        return instrumentation.getObjectSize(o);
    }
}
```
我們可以使用getObjectSize()方法來獲取任意Java對象的尺寸。
判斷Java對象的尺寸是大還是小,取決于多種因素,例如:
1. JVM版本
2. 堆大小
3. JVM垃圾回收策略(JVM設(shè)置)
4. 操作系統(tǒng)平臺
小對象的大小通常在2KB~128KB,超過這個大小的對象就是大對象。小對象被放置在TLA(Thread Local Area,線程局部區(qū)域)節(jié)中。TLA是從堆中保留的空閑內(nèi)存塊。它被交給一個Java線程使用。如果空間可用,年輕代空間保留TLA,或者它將使用舊空間。
可以在JVM設(shè)置項中配置該尺寸:
1. -XXtiaSize
2. -XXlargeObjectLimit
大對象不適合TLA,因此直接在堆中分配。大對象的內(nèi)存分配需要線程的同步。JVM使用了一組空閑內(nèi)存塊的緩存來:
1. 最小化同步需求
2. 加速內(nèi)存分配
在Java語言中,當使用new()方法調(diào)用構(gòu)造函數(shù)時,JVM會為對象分配內(nèi)存。

4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。
1. YGC頻繁:那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC
2. YGC的STW過長:如果有大量的對象要復(fù)制,就會導(dǎo)致STW時間過長
3. FGC過于頻繁:像Image對象存儲了高清圖像或者為數(shù)組分配了大量內(nèi)存時,導(dǎo)致大對象進入了老年代,F(xiàn)GC可能就比較頻繁
4. FGC的STW過長:堆中的碎片過多,或者FGC時OS有交換空間的操作或網(wǎng)絡(luò)通信的操作活動

論壇徽章:
8
2017金雞報曉
日期:2017-01-10 15:13:2915-16賽季CBA聯(lián)賽之天津
日期:2019-06-20 14:25:4015-16賽季CBA聯(lián)賽之天津
日期:2019-08-20 23:06:5319周年集字徽章-慶
日期:2019-08-27 13:24:4219周年集字徽章-19
日期:2019-09-06 18:55:5019周年集字徽章-年
日期:2019-09-06 18:55:5019周年集字徽章-周
日期:2019-09-20 17:18:2220周年集字徽章-CU
日期:2020-11-11 13:06:03
6 [報告]
發(fā)表于 2021-09-19 16:45 |只看該作者
(1)請詳細說說你所知道的Java類的生命周期。
Java類的生命周期類從被加載到虛擬機內(nèi)存開始,到卸載出內(nèi)存為止,整個生命周期包括:加載、驗證、準備、解析、初始化、使用和卸載七個階段。 其中加載、驗證、準備、初始化、和卸載這5個階段的順序是確定的。

(2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?
運行時數(shù)據(jù)區(qū)主要分為以下幾個部分:
·方法區(qū)
·虛擬機棧
·本地方法棧
·堆
·程序計數(shù)器
其中,按照線程在各個區(qū)域的數(shù)據(jù)是否共享劃分為:
·線程共享部分:方法區(qū)、Java 堆以及運行時常量池(歸屬于方法區(qū))
·線程私有部分:虛擬機棧、本地方法棧、程序計數(shù)器

JVM規(guī)范規(guī)定,JVM 在執(zhí)行 Java 程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。這些區(qū)域都有各自的用途。以及創(chuàng)建和銷毀的時間,有的區(qū)域隨著虛擬機進程的啟動就存在了,而有些區(qū)域則依賴用戶線程的啟動和結(jié)束而建立和銷毀。JVM 規(guī)范對 JVM 定義了運行時統(tǒng)一的內(nèi)存劃分規(guī)范,統(tǒng)一了標準,類似于 JDBC 規(guī)范一樣。其內(nèi)存區(qū)域劃分規(guī)范對于 JVM 的含義類似于我們 Java 中的接口,都是起到了規(guī)范的作用,JVM 是一臺可以運行 Java 應(yīng)用程序的抽象的計算機。

(3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。
虛擬機遇到一條new指令時,首先檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用,并檢查這個符號引用代表的類是否已經(jīng)被加載、解析和初始化過。如果沒有,先執(zhí)行相應(yīng)的類加載過程。虛擬機為新生對象分配內(nèi)存。對象所需內(nèi)存大小在類加載完成后就可以確定,為對象分配內(nèi)存等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來。
內(nèi)存分配的方式有兩種:① 指針碰撞: java堆如果規(guī)整,一邊是用過的內(nèi)存,一邊是空閑的內(nèi)存,中間一個指針作為邊界指示器; 分配內(nèi)存只需向空閑那邊移動指針空出與對象大小相等的空間;
② 空閑列表: 如果不規(guī)整,即用過的和空閑的內(nèi)存相互交錯;則虛擬機需要維護一個列表,記錄哪些內(nèi)存可用;分配內(nèi)存時查表找到一個足夠大的內(nèi)存,并更新列表記錄。
選擇哪種分配方式是根據(jù)這個虛擬機所采用的垃圾收集器是否帶有壓縮整理功能決定的:如果虛擬機的虛擬器帶壓縮整理功能,則系統(tǒng)采用指針碰撞的內(nèi)存分配算法;否則采用空閑列表的算法。
并發(fā)時,上面兩種方式分配內(nèi)存的操作都不是線程安全的,有兩種解決方案:
① 同步處理
JVM采用CAS(Compare and Swap)機制加上失敗重試的方式,保證更新操作的原子性;
CAS:有3個操作數(shù),內(nèi)存值V,舊的預(yù)期值A(chǔ),要修改的新值B。當且僅當預(yù)期值A(chǔ)和內(nèi)存值V相同時,將內(nèi)存值V修改為B,否則什么都不做;
② 本地線程分配緩沖區(qū)(TLAB)
把分配內(nèi)存的動作按照線程劃分在不同的空間中進行:每個線程在Java堆預(yù)先分配一小塊內(nèi)存,稱為本地線程分配緩沖區(qū)(Thread Local Allocation Buffer,TLAB);哪個線程需要分配內(nèi)存就從哪個線程的TLAB上分配;只有TLAB用完需要分配新的TLAB時,才需要同步處理。
JVM通過"-XX:+/-UseTLAB"指定是否使用TLAB。
內(nèi)存分配完之后,虛擬機需要將分配到的內(nèi)存空間都初始化為零值。如果用TLAB,則在TLAB分配時進行。這保證了程序中對象(及實例變量)不顯式初始賦零值,程序也能訪問到零值。
虛擬機對對象進行必要的設(shè)置,例如這個對象是哪個類的實例、 如何才能找到類的元數(shù)據(jù)信息、 對象的哈希碼、 對象的GC分代年齡等信息。這些信息存放在對象的對象頭(Object Header)之中。
執(zhí)行init方法,即按照程序員的意愿進行初始化。至此真正可用的對象才算完全被構(gòu)造出來。

(4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。
導(dǎo)致FGC問題的可能原因包括:
1、大對象:系統(tǒng)一次性加載了過多數(shù)據(jù)到內(nèi)存中(比如SQL查詢未做分頁),導(dǎo)致大對象進入了老年代。
2、內(nèi)存泄漏:頻繁創(chuàng)建了大量對象,但是無法被回收(比如IO對象使用完后未調(diào)用close方法釋放資源),先引發(fā)FGC,最后導(dǎo)致OOM.
3、程序頻繁生成一些長生命周期的對象,當這些對象的存活年齡超過分代年齡時便會進入老年代,最后引發(fā)FGC. (即本文中的案例)
4、程序BUG導(dǎo)致動態(tài)生成了很多新類,使得 Metaspace 不斷被占用,先引發(fā)FGC,最后導(dǎo)致OOM.
5、代碼中顯式調(diào)用了gc方法,包括自己的代碼甚至框架中的代碼。
6、JVM參數(shù)設(shè)置問題:包括總內(nèi)存大小、新生代和老年代的大小、Eden區(qū)和S區(qū)的大小、元空間大小、垃圾回收算法等等。

導(dǎo)致YGC問題的可能原因包括:
1、對存活對象標注時間過長:比如重載了Object類的Finalize方法,導(dǎo)致標注Final Reference耗時過長;或者String.intern方法使用不當,導(dǎo)致YGC掃描StringTable時間過長。
2、長周期對象積累過多:比如本地緩存使用不當,積累了太多存活對象;或者鎖競爭嚴重導(dǎo)致線程阻塞,局部變量的生命周期變長。
YGC問題其實比較難排查。相比FGC或者OOM,YGC的日志很簡單,只知道新生代內(nèi)存的變化和耗時,同時dump出來的堆內(nèi)存必須要仔細排查才行。

論壇徽章:
0
7 [報告]
發(fā)表于 2021-09-27 20:08 |只看該作者
好書,大力支持!

論壇徽章:
43
15-16賽季CBA聯(lián)賽之上海
日期:2020-11-04 09:36:5515-16賽季CBA聯(lián)賽之北控
日期:2018-10-29 18:20:3415-16賽季CBA聯(lián)賽之北京
日期:2018-10-06 21:39:5715-16賽季CBA聯(lián)賽之天津
日期:2018-08-09 10:30:41ChinaUnix元老
日期:2018-08-03 17:26:00黑曼巴
日期:2018-07-13 09:53:5415-16賽季CBA聯(lián)賽之吉林
日期:2018-03-30 12:58:4315-16賽季CBA聯(lián)賽之佛山
日期:2017-12-01 10:26:3815-16賽季CBA聯(lián)賽之上海
日期:2017-11-14 09:20:5015-16賽季CBA聯(lián)賽之江蘇
日期:2019-02-20 09:53:3319周年集字徽章-慶
日期:2019-08-27 13:23:2515-16賽季CBA聯(lián)賽之廣夏
日期:2019-09-03 18:29:06
8 [報告]
發(fā)表于 2021-09-30 16:04 |只看該作者
(1)請詳細說說你所知道的Java類的生命周期。
一個java類的完整的生命周期會經(jīng)歷加載、連接、初始化、使用、和卸載五個階段

(2)Java是如何對運行時數(shù)據(jù)區(qū)進行劃分的?為什么要這么劃分?
運行時數(shù)據(jù)區(qū)通常包括這幾個部分:程序計數(shù)器(Program Counter Register)、Java棧(VM Stack)、本地方法棧(Native Method Stack)、方法區(qū)(Method Area)、堆(Heap)。

(3)詳細說一下虛擬機為Java對象分配內(nèi)存的過程,越詳細越好。
1、應(yīng)用發(fā)起請求,要求系統(tǒng)分配內(nèi)存
  1)、init階段,final和static修飾的類和方法
  2)、應(yīng)用中new()方法
  3)、創(chuàng)建類時創(chuàng)建父類的對象申請內(nèi)存
  4)、java動態(tài)創(chuàng)建對象時反射技術(shù)(javaassist、asm等)
2、內(nèi)存發(fā)起申請的步驟
1)、創(chuàng)建對象實例
2)、為此對象分配內(nèi)存
3)、指針指向內(nèi)存地址
3、內(nèi)存申請過程中對jvm內(nèi)存模型的使用

  1)、對象在創(chuàng)建階段,在resolve階段,會對靜態(tài)化屬性值進行內(nèi)存分配,并初始化值=0(此時test=0),如果是有final static修飾的則將初始化值為定義值(此時test=10)private final static int test = 10;這樣靜態(tài)修飾的屬性值分配在方法區(qū)。
  2)、一個方法的開始,首先是方法的參數(shù)屬性、返回值等入棧,在棧區(qū)分配空間,同時如果有對象的new則需要去堆中建立對象實例。
  3)、在堆中創(chuàng)建對象實例時,一般是兩種方式,列表和指針碰撞。在指向堆中的實例時候,一般也是兩種方式,直接指向(如果方法變化會需要重新指定)和通過句柄池(會使用額外的空間存儲句柄)
  4)程序計數(shù)器 可以看做一個數(shù)據(jù)結(jié)構(gòu),在線程切換時候記錄下當前的字節(jié)行數(shù)和狀態(tài),以便于切回后能快速定位執(zhí)行
5、堆和堆內(nèi)存分配
  1)、堆的初始化

  2)、堆內(nèi)存分配
  3)、堆回收

(4)假設(shè)年輕代采用復(fù)制算法,老年代采用“標記-整理”算法管理虛擬機堆時,當線上發(fā)生YGC過于頻繁、YGC的STW過長、FGC過于頻繁、FGC的STW過長這幾種情況時,請列舉每個現(xiàn)象發(fā)生的可能原因,要有理有據(jù)。例如,YGC頻繁,那么可能是年輕代采用了單線程的復(fù)制算法導(dǎo)致內(nèi)存回收效率低下,而內(nèi)存的分配速度大時就造成了年輕代的內(nèi)存吃緊,又或者年輕代分配的內(nèi)存過小而又不能動態(tài)擴容的情況下導(dǎo)致頻繁YGC。

如果對象在 Eden 出生并經(jīng)過第一次 Minor GC 后仍然能夠存活,并且能被 Survivor 容納的話,將被移動到 Survivor 空間中,并將對象年齡設(shè)為 1.對象在 Survivor 中每熬過一次 MinorGC,年齡就增加 1 歲,當它的年齡增加到一定程度(默認為 15 歲),就會被晉升到老年代中。對象晉升到老年代的年齡閾值,可以通過參數(shù) -XX:MaxTenuringThreshold 來設(shè)置(但是最大只能是15,因為給該年齡預(yù)留的只有4個bit,也就是最大是1111。等于15)。
為了更好的適應(yīng)不同程序的內(nèi)存情況,虛擬機不是永遠要求對象年齡必須達到了某個值才能進入老年代,如果 Survivor 空間中相同年齡所有對象大小的總和大于 Survivor 空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代,無需達到要求的年齡。




論壇徽章:
0
9 [報告]
發(fā)表于 2021-10-08 11:35 |只看該作者
東風玖哥 發(fā)表于 2021-09-17 10:00
(1)請詳細說說你所知道的Java類的生命周期。一個java類的完整的生命周期會經(jīng)歷加載、連接、初始化、使用 ...

二樓說的已經(jīng)很好了,感覺沒有法補充了。

論壇徽章:
59
2015七夕節(jié)徽章
日期:2015-08-24 11:17:25ChinaUnix專家徽章
日期:2015-07-20 09:19:30每周論壇發(fā)貼之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38榮譽版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年紀念徽章
日期:2015-07-20 11:05:27IT運維版塊每日發(fā)帖之星
日期:2015-07-20 11:05:34操作系統(tǒng)版塊每日發(fā)帖之星
日期:2015-07-20 11:05:36程序設(shè)計版塊每日發(fā)帖之星
日期:2015-07-20 11:05:40數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-07-20 11:05:432015年辭舊歲徽章
日期:2015-07-20 11:05:44
10 [報告]
發(fā)表于 2021-10-09 17:14 |只看該作者
wangbin 發(fā)表于 2021-10-08 11:35
二樓說的已經(jīng)很好了,感覺沒有法補充了。

那是三樓了。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP