一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

從Java 8升級(jí)到Java 17全過(guò)程

jf_ro2CN3Fa ? 來(lái)源:芋道源碼 ? 作者:芋道源碼 ? 2022-11-03 14:13 ? 次閱讀


最近在做 Java8 到 Java17 的遷移工作,前期做了一些準(zhǔn)備,但是在升級(jí)過(guò)程還是有些問(wèn)題,太emo了,一些信息記錄如下,分為幾個(gè)部分:

  • 編譯相關(guān)
  • 參數(shù)遷移相關(guān)
  • 運(yùn)行相關(guān)

前人栽樹(shù)后人乘涼,有需要升級(jí)的可以參考一下,避免踩坑。。。

編譯相關(guān)

JEP 320

在 Java11 中引入了一個(gè)提案 JEP 320: Remove the Java EE and CORBA Modules (openjdk.org/jeps/320) 提案,移除了 Java EE and CORBA 的模塊,如果項(xiàng)目中用到需要手動(dòng)引入。比如代碼中用到了 javax.annotation.* 下的包:

publicabstractclassFridayAgent
@PreDestroy
publicvoiddestroy(){
agentClient.close();
}
}

在編譯時(shí)會(huì)找不到相關(guān)的類。這是因?yàn)?Java EE 已經(jīng)在 Java 9 中被標(biāo)記為 deprecated,Java 11 中被正式移除,可以手動(dòng)引入 javax 的包:


javax.annotation
javax.annotation-api
1.3.2

使用了 sun.misc.* 下的包

比如 sun.misc.BASE64Encoder,這個(gè)簡(jiǎn)單,替換一下工具類即可。

[ERROR]symbol:classBASE64Encoder
[ERROR]location:packagesun.misc

netty 低版本使用了 sun.misc.*,編譯錯(cuò)誤信息如下

Causedby:java.lang.NoClassDefFoundError:Couldnotinitializeclassio.netty.util.internal.PlatformDependent0
atio.netty.util.internal.PlatformDependent.getSystemClassLoader(PlatformDependent.java:694)~[netty-all-4.0.42.Final.jar!/:4.0.42.Final]

對(duì)應(yīng)的源碼如下:

/**
*The{@linkPlatformDependent}operationswhichrequiresaccessto{@codesun.misc.*}.
*/
finalclassPlatformDependent0{
}

https://github.com/netty/netty/issues/6855

lombok 使用了 com.sun.tools.javac.* 下的包

錯(cuò)誤信息如下:

Failed to execute goal org.apache.maven.plugins3.2:compile (default-compile) on project encloud-common: Fatal error compiling: java.lang.ExceptionInInitializerError: Unable to make field private com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs accessible: module jdk.compiler does not "opens com.sun.tools.javac.processing" to unnamed module

如果你的項(xiàng)目中使用 lombok,而且是低版本的話,就會(huì)出現(xiàn),lombok 的原理是在編譯期做一些手腳,用到了 com.sun.tools.javac 下的文件,升級(jí)到最新版可以解決。ps,個(gè)人很不喜歡 lombok, 調(diào)試的時(shí)候代碼和 class 對(duì)不上真的很惡心。

<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>

<version>1.18.24version>
dependency>

kotlin 版本限制

我們后端在很多年前就 all-in Kotlin,Kotlin 的升級(jí)也是我們的重中之重。

[ERROR] Failed to execute goal org.jetbrains.kotlin1.2.71:compile (compile) on project encloud-core: Compilation failure [ERROR] Unknown JVM target version: 17 [ERROR] Supported versions: 1.6, 1.8

Kotlin 在 1.6.0 版本開(kāi)始支持 Java17 的字節(jié)碼,低于 1.6.0 的編譯會(huì)直接報(bào)錯(cuò)

廢棄依賴分析

可以用 jdeps --jdk-internals --multi-release 17 --class-path . encloud-api.jar 來(lái)做項(xiàng)目的依賴分析

1743ec08-5b3e-11ed-a3b6-dac502259ad0.jpg

這樣你就可以知道哪些庫(kù)需要做升級(jí)了。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

參數(shù)遷移

什么是 Unified Logging

在 Java 領(lǐng)域,有廣為人知的日志框架,slf4j、log4j 等,這些框架提供了統(tǒng)一的編程接口,讓用戶可以通過(guò)簡(jiǎn)單的配置實(shí)現(xiàn)日志輸出的個(gè)性化配置,比如日志 tag、級(jí)別(info、debug 等)、上下文(線程 id、行號(hào)、時(shí)間等),在 JVM 內(nèi)部之前一直缺乏這樣的規(guī)范,于是出來(lái)了 Unified Logging,實(shí)現(xiàn)了日志格式的大一統(tǒng),這就是我們接下來(lái)要介紹的重點(diǎn) Unified Logging。

我們接觸最多的是 gc 的日志,在 java8 中,我們配置 gc 日志的參數(shù)是 -Xloggc:/tmp/gc.log。在 JVM 中除了 GC,還有大量的其它相關(guān)的日志,比如線程、os 等,在新的 Unified Logging 日志中,日志輸出的方式變更為了 java -Xlog:xxx,GC 不再特殊只是做為日志的一種存在形式。

java-Xlog-version

輸出結(jié)果如下:

174f20b4-5b3e-11ed-a3b6-dac502259ad0.jpg

可以看到日志輸出里,不僅有 GC 相關(guān)的日志,還有 os 線程相關(guān)的信息。事實(shí)上 java 的日志的生產(chǎn)者有非常多部分,比如 thread、class load、unload、safepoint、cds 等。

17663646-5b3e-11ed-a3b6-dac502259ad0.jpg

歸根到底,日志打印,需要回答清楚三個(gè)問(wèn)題:

  • what:要輸出什么信息(tag),以什么日志級(jí)別輸出(level)
  • where:輸出到哪里(console 還是 file)
  • decorators:日志如何

輸出什么信息(selectors)

首先來(lái)看 what 的部分,如何指定要輸出哪些信息,這個(gè)在 JVM 內(nèi)部被稱之為 selectors。

JVM 采用的是 =的形式來(lái)表示 selectors,默認(rèn)情況下,tag 為all,表示所有的 tag,level 為 INFOjava -Xlog -version 等價(jià)于下面的形式

java-Xlog:all=info-version

如果我們想輸出tag 為 gc,日志級(jí)別為 debug 的日志,可以用 java -Xlog:gc=debug 的形式:

$java-Xlog:gc=debug-version
[0.023s][info][gc]UsingG1
[0.023s][debug][gc]ConcGCThreads:3offset22
[0.023s][debug][gc]ParallelGCThreads:10
[0.024s][debug][gc]Initializemarkstackwith4096chunks,maximum524288

這樣就輸出了 tag 為 gc,級(jí)別為 debug 的日志信息。

不過(guò)這里有一個(gè)比較坑的點(diǎn)是,這里的 tag 匹配規(guī)則是精確匹配,如果某條日志的 tag 是 gc,metaspace,通過(guò)上面的規(guī)則是匹配不到的,我們可以手動(dòng)指定的方式來(lái)輸出。

$java-Xlog:gc+metaspace-version

[0.022s][info][gc,metaspace]CDSarchive(s)mappedat:...size12443648.
[0.022s][info][gc,metaspace]Compressedclassspacemappedat:reservedsize:...
[0.022s][info][gc,metaspace]Narrowklassbase:...,Narrow
klassshift:0,Narrowklassrange:0x100000000

這里的 selector 也是可以進(jìn)行組合的,不同的 selector 之間用逗號(hào)分隔即可。比如同時(shí)輸出 gcgc+metaspace 這兩類 tag 的日志,就可以這么寫(xiě):

$java-Xlog:gc=debug,gc+metaspace-version

[0.020s][info][gc]UsingG1
[0.020s][debug][gc]ConcGCThreads:3offset22
[0.020s][debug][gc]ParallelGCThreads:10
[0.020s][debug][gc]Initializemarkstackwith4096chunks,maximum524288
[0.022s][info][gc,metaspace]CDSarchive(s)mappedat:
[0.022s][info][gc,metaspace]Compressedclassspacemappedat:
[0.022s][info][gc,metaspace]Narrowklassbase:0x0000000800000000

當(dāng)然這么搞是很麻煩的,JVM 提供了通配符 * 來(lái)解決精確匹配的問(wèn)題,比如我們想要所有 tag 為 gc 的日志,可以這么寫(xiě):

$java-Xlog:gc*=debug-version

[0.024s][debug][gc,heap]Minimumheap8388608
[0.024s][info][gc]UsingG1
[0.024s][debug][gc,heap,coops]Heapaddress:0x0000000707400000
[0.024s][debug][gc]ConcGCThreads:3offset22
[0.024s][debug][gc]ParallelGCThreads:10
[0.024s][debug][gc]Initializemarkstackwith4096chunks
[0.024s][debug][gc,ergo,heap]Expandtheheap.requestedexpansionamount:
[0.025s][debug][gc,heap,region]Activateregions[0,125)[0.025s][debug][gc,ihop]Targetoccupancyupdate:old:0B,new:262144000B
[0.025s][debug][gc,ergo,refine]InitialRefinementZones:green:2560
[0.026s][debug][gc,task]G1ServiceThread
[0.026s][debug][gc,task]G1ServiceThread(PeriodicGCTask)(register)
[0.026s][info][gc,init]Version:17.0.3+7(release)
...

如果只想要 INFO 級(jí)別的日志,則可以省略 level 的設(shè)置,使用 java -Xlog:gc* -version 即可。

如果想知道有哪些個(gè)性化的 tag 可以選擇,可以用 java -Xlog:help 來(lái)找到所有可用的 tag。

階段性小結(jié)

17736456-5b3e-11ed-a3b6-dac502259ad0.jpg

第二部分:輸出到哪里(output)

默認(rèn)情況下,日志會(huì)輸出到 stdout,jvm 支持以下三種輸出方式:

  • stdout
  • stderr
  • file

一般而言我們會(huì)把日志輸出到文件中,方便后續(xù)進(jìn)一步分析

-Xlog:all=debug:file=/path_to_logs/app.log

還可以指定日志切割的大小和方式

-Xlogfile=/path_to_logs/app.log:filesize=104857600,filecount=5

第三部分:日志 decorators

每條日志除了正常的信息以外,還有不少日志相關(guān)的上下文信息,在 jvm 中被稱為 decorators,有下面這些可選項(xiàng)。

178ecf0c-5b3e-11ed-a3b6-dac502259ad0.png

比如可以用 java -Xlog:all=debuglevel,tags,time,uptime,pid -version 選項(xiàng)來(lái)打印日志。

[2022-06-15T1901.529+0800][0.001s][5235][info][os,thread]Threadattached
[2022-06-15T1901.529+0800][0.001s][5235][debug][os,thread]Thread5237stack...
[2022-06-15T1901.529+0800][0.001s][5235][debug][perf,datacreation]
Unified Logging 小結(jié)

輸出格式如下:

-Xlog:[selectors]:[output]:[decorators][:output-options]
  • selectors 是多個(gè) tag 和 level 的組合,起到了 what(過(guò)濾器)的作用,格式為 tag1[+tag2...][*][=level][,...]
  • decorators 是日志相關(guān)的描述信息,也可以理解為上下文
  • output 是輸出相關(guān)的選項(xiàng),一般我們會(huì)配置為輸出到文件,按文件大小切割

這里補(bǔ)充一個(gè)知識(shí)點(diǎn),就是默認(rèn)值:

  • tag:all
  • level:info
  • output:stdout
  • decorators: uptime, level, tags

GC 參數(shù)遷移

可以看到 GC 相關(guān)的參數(shù)都已經(jīng)收攏到 Xlog 下,以前的很多 Java8 下的參數(shù)已經(jīng)被移除或者標(biāo)記為過(guò)期。

比如 PrintGCDetails 已經(jīng)被 -Xlog:gc* 取代:

java-XX:+PrintGCDetails-version

[0.001s][warning][gc]-XX:+PrintGCDetailsisdeprecated.Willuse-Xlog:gc*instead.

常見(jiàn)的標(biāo)記為廢棄的參數(shù)還有 -XX:+PrintGC-Xloggc:,遷移前后的參數(shù)如下:

舊參數(shù) 新參數(shù)
-XX:+PrintGCDetails -Xlog:gc*
-XX:+PrintGC -Xlog:gc
-Xloggc: -Xlogfile=

除此之外,大量的 GC 的參數(shù)被移除,比如常用的參數(shù) -XX:+PrintTenuringDistribution,Java17 會(huì)拒絕啟動(dòng)

java-XX:+PrintTenuringDistribution-version
UnrecognizedVMoption'PrintTenuringDistribution'
Error:CouldnotcreatetheJavaVirtualMachine.
Error:Afatalexceptionhasoccurred.Programwillexit.

更詳細(xì)的移除的參數(shù)如下

CMSDumpAtPromotionFailure,
CMSPrintEdenSurvivorChunks,
GlLogLevel,
G1PrintHeapRegions,
G1PrintRegionLivenessInfo,
G1SummarizeConcMark,
G1SummarizeRSetStats,
G1TraceConcRefinement,
G1TraceEagerReclaimHumongousObjects,
G1TraceStringSymbolTableScrubbing,
GCLogFileSize,NumberofGCLogFiles,
PrintAdaptiveSizePolicy,
PrintclassHistogramAfterFullGC,
PrintClassHistogramBeforeFullGC,
PrintCMSInitiationStatistics
PrintCMSStatistics,
PrintFLSCensus,
PrintFLSStatistics,
PrintGCApplicationConcurrentTime
PrintGCApplicationStoppedTime,
PrintGCCause,
PrintGCDateStamps,
PrintGCID,
PrintGCTaskTimeStamps,
PrintGCTimeStamps,
PrintHeapAtGC,
PrintHeapAtGCExtended,
PrintJNIGCStalls,
PrintOldPLAB
PrintParallel0ldGCPhaseTimes,
PrintPLAB,
PrintPromotionFailure,
PrintReferenceGC,
PrintStringDeduplicationStatistics,
PrintTaskqueue,
PrintTenuringDistribution,
PrintTerminationStats,
PrintTLAB,
TraceDynamicGCThreads,
TraceMetadataHumongousAllocation,
UseGCLogFileRotation,
VerifySilently

這些移除的參數(shù)大部分都能在新的日志體系下找到對(duì)應(yīng)的參數(shù),比如 PrintHeapAtGC 這個(gè)參數(shù)可以用 -Xlog:gc+heap=debug 來(lái)替代

$java-Xlog:gc+heap=debug-cp.G1GCDemo01

[0.004s][debug][gc,heap]Minimumheap8388608Initialheap268435456Maximumheap
hello,g1gc!
[12.263s][debug][gc,heap]GC(0)HeapbeforeGCinvocations=0(full0):
[12.265s][debug][gc,heap]GC(0)garbage-firstheap
[12.265s][debug][gc,heap]GC(0)regionsize2048K,1young(2048K)
[12.265s][debug][gc,heap]GC(0)Metaspaceused3678K
[12.265s][debug][gc,heap]GC(0)classspaceused300K
[12.280s][debug][gc,heap]GC(0)Uncommittableregionsaftershrink:124

雖然理解起來(lái)不太直觀,不過(guò)要記住 -XX:+PrintGCApplicationStoppedTime-XX+PrintGCApplicationConcurrentTime 這兩個(gè)參數(shù)一起被 -Xlog:safepoint 取代。

還有一個(gè)常見(jiàn)的參數(shù) -XX:+PrintAdaptiveSizePolicy-Xlog:gc+ergo*=trace 取代,

[0.122s][debug][gc,ergo,refine]InitialRefinementZones:green:23,yellow:
69,red:115,minyellowsize:46
[0.142s][debug][gc,ergo,heap]Expandtheheap.requestedexpansionamount:268435456Bexpansionamount:268435456B
[2.475s][trace][gc,ergo,cset]GC(0)StartchoosingCSet.pendingcards:0predictedbasetime:10.00msremainingtime:
190.00mstargetpausetime:200.00ms
[2.476s][trace][gc,ergo,cset]GC(9)AddyoungregionstoCSet.eden:24regions,survivors:0regions,predictedyoung
regiontime:367.19ms,targetpausetime:200.00ms
[2.476s][debug][gc,ergo,cset]GC(0)FinishchoosingCSet.old:0regions,predictedoldregiontime:0.00ms,time
remaining:0.00
[2.826s][debug][gc,ergo]GC(0)RunningG1ClearCardTableTaskusing1workersfor1unitsofworkfor24regions.
[2.827s][debug][gc,ergo]GC(0)RunningG1FreeCollectionSetusing1workersforcollectionsetlength24
[2.828s][trace][gc,ergo,refine]GC(0)UpdatingRefinementZones:updaterstime:0.004ms,updatersbuffers:0,updaters
goaltime:19.999ms
[2.829s][debug][gc,ergo,refine]GC(0)UpdatedRefinementZones:green:23,yellow:69,red:115
[3.045s][trace][gc,ergo,set]GC(1)StartchoosingCSet.pendingcards:5898predictedbasetime:26.69msremaining
time:173.31mstargetpausetime:200.00ms
[3.045s][trace][gc,ergo,cset]GC(1)AddyoungregionstoSet.eden:9regions,survivors:3regions,predictedyoung
regiontime:457.38ms,targetpausetime:200.00ms
[3.045s][debug](gc,ergo,set]GC(1)FinishchoosingCSet.old:@regions,predictedoldregiontime:0.00ms,time
remaining:0.00
[3.090s][debug][gc,ergo
]GC(1)RunningG1ClearCardTableTaskusing1workersfor1unitsofworkfor12regions.
[3.091s][debug][gc,ergo
GC(1)RunningG1FreeCollectionSetusing1workersforcollectionsetlength12
[3.093s][trace][gc,ergo,refine]GC(1)UpdatingRefinementZones:updaterstime:2.510ms,updatersbuffers:25,updaters
goaltime:19.999ms
[3.093s][debug][gc,ergo,refine]GC(1)UpdatedRefinementZones:green:25,yellow:75,red:125

看一下這部分的源碼的變遷,就可以知道確實(shí)是如此了,在 Java8 中,PSYoungGen::resize_spaces代碼如下:

179dedd4-5b3e-11ed-a3b6-dac502259ad0.jpg

在 Java17 中,這部分日志打印被 gc+ergo 的標(biāo)簽日志取代:

17aae3b8-5b3e-11ed-a3b6-dac502259ad0.jpg

還有一個(gè)分代 GC 中非常有用的參數(shù) -XX:+PrintTenuringDistribution,現(xiàn)在被 gc+age=trace 取代

完整的參數(shù)變遷對(duì)應(yīng)表如下:

17c35902-5b3e-11ed-a3b6-dac502259ad0.png17dd64dc-5b3e-11ed-a3b6-dac502259ad0.png18028df2-5b3e-11ed-a3b6-dac502259ad0.png18105270-5b3e-11ed-a3b6-dac502259ad0.png
舉例
-XX:+PrintGCDetails//gc*
-XX:+PrintGCApplicationStoppedTime//safepoint
-XX:+PrintGCApplicationConcurrentTime//safepoint
-XX:+PrintGCCause//默認(rèn)會(huì)輸出
-XX:+PrintGCID//默認(rèn)會(huì)輸出
-XX:+PrintTenuringDistribution//gc+age*=trace
-XX:+PrintGCDateStamps//:time,tags,level
-XX:+UseGCLogFileRotation//:filecount=5,filesize=10M
-XX:NumberOfGCLogFiles=5//:filecount=5,filesize=10M
-XX:GCLogFileSize=10M//:filecount=5,filesize=10M
-Xloggc:/var/log/`date+%FT%H-%M-%S`-gc.log//-Xlog::file=/var/log/%t-gc.log

變遷后:

-Xlog:
gc*,
safepoint,
gc+heap=debug,
gc+ergo*=trace,
gc+age*=trace,
:file=/var/log/%t-gc.log
:time,tags,level
:filecount=5,filesize=10M
推薦的配置
-Xlog:
//selections
codecache+sweep*=trace,
class+unload,//TraceClassUnloading
class+load,//TraceClassLoading
os+thread,
safepoint,//TraceSafepoint
gc*,//PrintGCDetails
gc+stringdedup=debug,//PrintStringDeduplicationStatistics
gc+ergo*=trace,
gc+age=trace,//PrintTenuringDistribution
gc+phases=trace,
gc+humongous=trace,
jit+compilation=debug
//output
:file=/path_to_logs/app.log
//decorators
:level,tags,time,uptime,pid
//output-options
:filesize=104857600,filecount=5

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

運(yùn)行相關(guān)

反射+私有 API 調(diào)用之傷

在 Java8 中,沒(méi)有人能阻止你訪問(wèn)特定的包,比如 sun.misc,對(duì)反射也沒(méi)有限制,只要 setAccessible(true) 就可以了。Java9 模塊化以后,一切都變了,只能通過(guò) --add-exports--add-opens 來(lái)打破模塊封裝

  • --add-opens 導(dǎo)出特定的包
  • --add-opens 允許模塊中特定包的類路徑深度反射訪問(wèn)

比如:

--add-opensjava.base/java.lang=ALL-UNNAMED
--add-opensjava.base/java.io=ALL-UNNAMED
--add-opensjava.base/java.math=ALL-UNNAMED
--add-opensjava.base/java.net=ALL-UNNAMED
--add-opensjava.base/java.nio=ALL-UNNAMED
--add-opensjava.base/java.security=ALL-UNNAMED
--add-opensjava.base/java.text=ALL-UNNAMED
--add-opensjava.base/java.time=ALL-UNNAMED
--add-opensjava.base/java.util=ALL-UNNAMED
--add-opensjava.base/jdk.internal.access=ALL-UNNAMED
--add-opensjava.base/jdk.internal.misc=ALL-UNNAMED

關(guān)于 GC 算法的選擇

CMS 正式退出歷史舞臺(tái),G1 正式接棒,ZGC 蓄勢(shì)待發(fā)。在GC 算法的選擇上,目前來(lái)看 G1 還是最佳的選擇,ZGC 因?yàn)橛袃?nèi)存占用被 OS 標(biāo)記過(guò)高(三倍共享內(nèi)存)虛高的問(wèn)題,進(jìn)程可能被 OOM-killer 殺掉。

ZGC 三倍 RES 內(nèi)存

ZGC 底層用到了一個(gè)稱之為染色指針的技術(shù),使用三個(gè)視圖(Marked0、Marked1 和 Remapped)來(lái)映射到同一塊共享內(nèi)存區(qū)域,原理如下:

##include
##include
##include
##include
##include
##include
##include

intmain(){
//shm_open()函數(shù)用來(lái)打開(kāi)或者創(chuàng)建一個(gè)共享內(nèi)存區(qū),兩個(gè)進(jìn)程可以通過(guò)給shm_open()函數(shù)傳遞相同的名字以達(dá)到操作同一共享內(nèi)存的目的
intfd=::shm_open("/test",O_RDWR|O_CREAT|O_EXCL,0600);
if(fd0){
shm_unlink("/test");
perror("shmopenfailed");
return0;
}

size_tsize=1*1024*1024*1024;
//創(chuàng)建一個(gè)共享內(nèi)存后,默認(rèn)大小為0,所以需要設(shè)置共享內(nèi)存大小。ftruncate()函數(shù)可用來(lái)調(diào)整文件或者共享內(nèi)存的大小
::ftruncate(fd,size);
intprot=PROT_READ|PROT_WRITE;
//創(chuàng)建共享內(nèi)存后,需要將共享內(nèi)存映射到調(diào)用進(jìn)程的地址空間,可通過(guò)mmap()函數(shù)來(lái)完成
uint32_t*p1=(uint32_t*)(mmap(nullptr,size,prot,MAP_SHARED,fd,0));
uint32_t*p2=(uint32_t*)(mmap(nullptr,size,prot,MAP_SHARED,fd,0));
uint32_t*p3=(uint32_t*)(mmap(nullptr,size,prot,MAP_SHARED,fd,0));
::close(fd);
*p1=0xcafebabe;
::printf("Addressofaddr1:%p,valueis0x%x
",p1,*p1);
::printf("Addressofaddr2:%p,valueis0x%x
",p2,*p2);
::printf("Addressofaddr3:%p,valueis0x%x
",p3,*p3);
::getchar();
*p2=0xcafebaba;
::printf("Addressofaddr1:%p,valueis0x%x
",p1,*p1);
::printf("Addressofaddr2:%p,valueis0x%x
",p2,*p2);
::printf("Addressofaddr3:%p,valueis0x%x
",p3,*p3);
::getchar();
munmap(p1,size);
munmap(p2,size);
munmap(p3,size);
shm_unlink("/test");
std::cout<"hello"<std::endl;
}

你可以想象 p1、p2、p3 這三塊內(nèi)存區(qū)域就是 ZGC 中三種視圖。

但是在 linux 統(tǒng)計(jì)中,雖然是共享內(nèi)存,但是依然會(huì)統(tǒng)計(jì)三次,比如 RES。

同一個(gè)應(yīng)用,使用 G1 RES 顯示占用 2G,ZGC 則顯示占用 6G

java-XX:+AlwaysPreTouch-Xms2G-Xmx2G-XX:+UseZGCMyTest
java-XX:+AlwaysPreTouch-Xms2G-Xmx2G-XX:+UseG1GCMyTest
181e2738-5b3e-11ed-a3b6-dac502259ad0.jpg

接下面我們討論的都是 G1 相關(guān)的。

G1 參數(shù)調(diào)整

不要配置新生代的大小

這個(gè)在《JVM G1 源碼分析和調(diào)優(yōu)》一書(shū)里有詳細(xì)的介紹,有兩個(gè)主要的原因:

  • G1對(duì)內(nèi)存的管理是不連續(xù)的,重新分配一個(gè)分區(qū)代價(jià)很低
  • G1 的需要根據(jù)目標(biāo)停頓時(shí)間動(dòng)態(tài)調(diào)整搜集的分區(qū)的個(gè)數(shù),如果不能調(diào)整新生代的大小,那么 G1 可能不能滿足停頓時(shí)間的要求

諸如 -Xmn, -XX:NewSize, -XX:MaxNewSize, -XX:SurvivorRatio 都不要在 G1 中出現(xiàn),只需要控制最大、最小堆和目標(biāo)暫停時(shí)間即可

調(diào)整 -XX:InitiatingHeapOccupancyPercent 到合適的值

IHOP 默認(rèn)值為 45,這個(gè)值是啟動(dòng)并發(fā)標(biāo)記的先決條件,只有當(dāng)老年代內(nèi)存??偪臻g的 45% 之后才會(huì)啟動(dòng)并發(fā)標(biāo)記任務(wù)。

增加這個(gè)值:導(dǎo)致并發(fā)標(biāo)記可能花費(fèi)更多的時(shí)間,同時(shí)導(dǎo)致 YGC 和 Mixed-GC 收集時(shí)的分區(qū)數(shù)變少,可以根據(jù)整體應(yīng)用占用的平均內(nèi)存來(lái)設(shè)置。



審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2983

    瀏覽量

    106524
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    674

    瀏覽量

    33614
  • 遷移
    +關(guān)注

    關(guān)注

    0

    文章

    34

    瀏覽量

    8023

原文標(biāo)題:從 Java 8 升級(jí)到 Java 17 全過(guò)程,賊特么坑!

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    6.12.1升級(jí)到6.13老是閃退是什么原因?qū)е碌模?/a>

    6.12.1升級(jí)到6.13老是閃退,回到6.12.1又正常,問(wèn)一下大家是什么原因?qū)е?,有什么解決辦法?
    發(fā)表于 03-11 08:13

    Java應(yīng)用OOM問(wèn)題的排查過(guò)程

    導(dǎo)讀 本文記錄最近一例Java應(yīng)用OOM問(wèn)題的排查過(guò)程,希望可以給遇到類似問(wèn)題的同學(xué)提供參考。 前言:此文記錄最近一例Java應(yīng)用OOM問(wèn)題的排查過(guò)程,希望可以給遇到類似問(wèn)題的同學(xué)提供
    的頭像 發(fā)表于 02-12 11:15 ?462次閱讀
    <b class='flag-5'>Java</b>應(yīng)用OOM問(wèn)題的排查<b class='flag-5'>過(guò)程</b>

    Java 23功能介紹

    Java 23 包含全新和更新的 Java 語(yǔ)言功能、核心 API 以及 JVM,同時(shí)適合新的 Java 開(kāi)發(fā)者和高級(jí)開(kāi)發(fā)者。?IntelliJ IDEA 2024.2?開(kāi)始已支持
    的頭像 發(fā)表于 12-04 10:02 ?736次閱讀
    <b class='flag-5'>Java</b> 23功能介紹

    Java集合API的改進(jìn)介紹

    解答這些問(wèn)題。 我們將逐步學(xué)習(xí) Java 集合類的優(yōu)化過(guò)程,并按版本逐一對(duì)比分析。主要討論的焦點(diǎn)將包括 JDK 1.0、1.2、1.4、1.5、1.6、1.8、9、10、11 和 21 版本的 Java 集合功能
    的頭像 發(fā)表于 11-22 11:12 ?446次閱讀
    <b class='flag-5'>Java</b>集合API的改進(jìn)介紹

    Java中時(shí)間戳的使用

    Java中時(shí)間戳的使用
    的頭像 發(fā)表于 11-06 16:04 ?414次閱讀
    <b class='flag-5'>Java</b>中時(shí)間戳的使用

    ADS7813升級(jí)到ADS8513

    電子發(fā)燒友網(wǎng)站提供《ADS7813升級(jí)到ADS8513.pdf》資料免費(fèi)下載
    發(fā)表于 10-21 09:59 ?0次下載
    <b class='flag-5'>從</b>ADS7813<b class='flag-5'>升級(jí)到</b>ADS8513

    java反編譯能拿到源碼嗎

    Java反編譯是一種將編譯后的Java字節(jié)碼(.class文件)轉(zhuǎn)換回Java源代碼的過(guò)程。雖然反編譯可以幫助理解代碼的邏輯和結(jié)構(gòu),但它并不總是能完美地還原原始源代碼。反編譯工具通常會(huì)
    的頭像 發(fā)表于 09-02 11:03 ?1556次閱讀

    ESP8266 12E如何升級(jí)到最新固件?

    ESP8266 12E如何升級(jí)到最新固件
    發(fā)表于 07-22 07:03

    將Non-OS SDK1.3.0升級(jí)到1.4.0后,AT CWLAP命令將無(wú)法再找到我的AP,為什么?

    將Non-OS SDK1.3.0升級(jí)到1.4.0(AT版本0.40升級(jí)到0.50)后,AT CWLAP命令將無(wú)法再找到我的AP。它仍然會(huì)找到一些 AP,但不是我想使用的 AP,它在物理上最接近
    發(fā)表于 07-17 06:00

    華納云:java web和java有什么區(qū)別java web和java有什么區(qū)別

    的平臺(tái),Java可以用于開(kāi)發(fā)桌面應(yīng)用程序、移動(dòng)應(yīng)用程序、企業(yè)級(jí)應(yīng)用程序等。 – Java Web是Java語(yǔ)言在Web開(kāi)發(fā)領(lǐng)域的應(yīng)用,它使用Java
    的頭像 發(fā)表于 07-16 13:35 ?1270次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別

    JDK8升級(jí)JDK11最全實(shí)踐干貨來(lái)了

    應(yīng)用程序的運(yùn)行速度。綜合評(píng)估,Java 8 升級(jí)到 Java 11,G1GC平均速度提升16.1%,ParallelGC為4.5%(基于O
    的頭像 發(fā)表于 06-25 14:51 ?741次閱讀
    JDK<b class='flag-5'>8</b><b class='flag-5'>升級(jí)</b>JDK11最全實(shí)踐干貨來(lái)了

    JDK11升級(jí)JDK17最全實(shí)踐干貨來(lái)了

    解決你的問(wèn)題。 上篇文章給大家?guī)?lái)了JDK8升級(jí)JDK11的最全實(shí)踐,相信大家閱讀后已經(jīng)對(duì)JDK11有了比較深入的了解。2021年9月14日,Oracle發(fā)布了可以長(zhǎng)期支持的JDK17版本,那么
    的頭像 發(fā)表于 06-25 14:50 ?1088次閱讀
    JDK11<b class='flag-5'>升級(jí)</b>JDK<b class='flag-5'>17</b>最全實(shí)踐干貨來(lái)了

    精準(zhǔn)毫米:H9激光切管機(jī)鋁材切割與打孔全過(guò)程解析

    H9激光切管機(jī)在鋁材切割與打孔的全過(guò)程包括設(shè)定參數(shù)、啟動(dòng)切割、監(jiān)控質(zhì)量、完成取件和檢查效果等。H9激光切管機(jī)鋁材切割與打孔的全過(guò)程可以詳細(xì)解析如下:一、操作準(zhǔn)備檢查H9激光切管機(jī)各部件是否齊全,并
    的頭像 發(fā)表于 06-20 11:14 ?1000次閱讀
    精準(zhǔn)<b class='flag-5'>到</b>毫米:H9激光切管機(jī)鋁材切割與打孔<b class='flag-5'>全過(guò)程</b>解析

    VSCode使用ESP-IDF插件1.50升級(jí)到1.5.1之后Monitor快捷鍵命令報(bào)錯(cuò)怎么解決?

    系統(tǒng)環(huán)境:Win7 IDF版本:V4.2.1 VSCode版本:1.70.1 硬件芯片:ESP32-PICO-D4 問(wèn)題描述: 1.ESP-IDF插件升級(jí)到1.5.1之后Monitor快捷鍵命令報(bào)錯(cuò),報(bào)錯(cuò)日志如下 2.回滾到1.5.0版本后功能正常,日志如下:
    發(fā)表于 06-13 06:54

    如何將stm32f207的以太網(wǎng)庫(kù)中l(wèi)wip1.3.2升級(jí)到1.4.1?

    如何將stm32f207的以太網(wǎng)庫(kù)中l(wèi)wip1.3.2升級(jí)到1.4.1
    發(fā)表于 05-17 08:04