chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

從Java 8升級到Java 17全過程

jf_ro2CN3Fa ? 來源:芋道源碼 ? 作者:芋道源碼 ? 2022-11-03 14:13 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群


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

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

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

編譯相關(guān)

JEP 320

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

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

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


javax.annotation
javax.annotation-api
1.3.2

使用了 sun.misc.* 下的包

比如 sun.misc.BASE64Encoder,這個簡單,替換一下工具類即可。

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

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

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]

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

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

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

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

錯誤信息如下:

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,而且是低版本的話,就會出現(xiàn),lombok 的原理是在編譯期做一些手腳,用到了 com.sun.tools.javac 下的文件,升級到最新版可以解決。ps,個人很不喜歡 lombok, 調(diào)試的時候代碼和 class 對不上真的很惡心。

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

<version>1.18.24version>
dependency>

kotlin 版本限制

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

[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 版本開始支持 Java17 的字節(jié)碼,低于 1.6.0 的編譯會直接報(bào)錯

廢棄依賴分析

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

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

這樣你就可以知道哪些庫需要做升級了。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(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)一的編程接口,讓用戶可以通過簡單的配置實(shí)現(xiàn)日志輸出的個性化配置,比如日志 tag、級別(info、debug 等)、上下文(線程 id、行號、時間等),在 JVM 內(nèi)部之前一直缺乏這樣的規(guī)范,于是出來了 Unified Logging,實(shí)現(xiàn)了日志格式的大一統(tǒng),這就是我們接下來要介紹的重點(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

歸根到底,日志打印,需要回答清楚三個問題:

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

輸出什么信息(selectors)

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

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

java-Xlog:all=info-version

如果我們想輸出tag 為 gc,日志級別為 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,級別為 debug 的日志信息。

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

$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 之間用逗號分隔即可。比如同時輸出 gcgc+metaspace 這兩類 tag 的日志,就可以這么寫:

$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 提供了通配符 * 來解決精確匹配的問題,比如我們想要所有 tag 為 gc 的日志,可以這么寫:

$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 級別的日志,則可以省略 level 的設(shè)置,使用 java -Xlog:gc* -version 即可。

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

階段性小結(jié)

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

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

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

  • stdout
  • stderr
  • file

一般而言我們會把日志輸出到文件中,方便后續(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)來打印日志。

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

這里補(bǔ)充一個知識點(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)記為過期。

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

java-XX:+PrintGCDetails-version

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

常見的標(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 會拒絕啟動

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ù)大部分都能在新的日志體系下找到對應(yīng)的參數(shù),比如 PrintHeapAtGC 這個參數(shù)可以用 -Xlog:gc+heap=debug 來替代

$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

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

還有一個常見的參數(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

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

完整的參數(shù)變遷對應(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)會輸出
-XX:+PrintGCID//默認(rèn)會輸出
-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ǒng) + 用戶小程序,支持 RBAC 動態(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 中,沒有人能阻止你訪問特定的包,比如 sun.misc,對反射也沒有限制,只要 setAccessible(true) 就可以了。Java9 模塊化以后,一切都變了,只能通過 --add-exports--add-opens 來打破模塊封裝

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

比如:

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

ZGC 三倍 RES 內(nèi)存

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

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

intmain(){
//shm_open()函數(shù)用來打開或者創(chuàng)建一個共享內(nèi)存區(qū),兩個進(jìn)程可以通過給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)建一個共享內(nèi)存后,默認(rèn)大小為0,所以需要設(shè)置共享內(nèi)存大小。ftruncate()函數(shù)可用來調(diào)整文件或者共享內(nèi)存的大小
::ftruncate(fd,size);
intprot=PROT_READ|PROT_WRITE;
//創(chuàng)建共享內(nèi)存后,需要將共享內(nèi)存映射到調(diào)用進(jìn)程的地址空間,可通過mmap()函數(shù)來完成
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)存,但是依然會統(tǒng)計(jì)三次,比如 RES。

同一個應(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)整

不要配置新生代的大小

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

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

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

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

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

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



審核編輯 :李倩


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

    關(guān)注

    20

    文章

    2997

    瀏覽量

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

    關(guān)注

    0

    文章

    691

    瀏覽量

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

    關(guān)注

    0

    文章

    34

    瀏覽量

    8162

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

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    芯片燒錄原理是什么?一文讀懂芯片程序燒錄全過程

    芯片燒錄是向芯片存儲單元寫入二進(jìn)制代碼的精密操作,核心是借燒錄器以特定電壓和時序改變浮柵晶體管電荷狀態(tài)。全過程分五步:建立連接核對芯片 ID,擦除存儲器原有數(shù)據(jù),按協(xié)議將程序文件逐位寫入芯片,實(shí)時
    的頭像 發(fā)表于 12-25 14:20 ?294次閱讀

    醫(yī)院隨訪管理系統(tǒng)源碼,三隨訪系統(tǒng)源碼,Java+Springboot,Vue,Ant-Design+MySQL5

    Java版隨訪系統(tǒng)源碼,醫(yī)院隨訪管理系統(tǒng)源碼,三隨訪系統(tǒng)源碼,B/S前后端分離架構(gòu),自主版權(quán),落地案例。 技術(shù)框架:Java+Springboot,Vue,Ant-Design+MySQL5 開發(fā)
    的頭像 發(fā)表于 11-08 14:48 ?311次閱讀
    醫(yī)院隨訪管理系統(tǒng)源碼,三<b class='flag-5'>級</b>隨訪系統(tǒng)源碼,<b class='flag-5'>Java</b>+Springboot,Vue,Ant-Design+MySQL5

    Arm Neoverse CPU上大代碼量Java應(yīng)用的性能測試

    Java 是互聯(lián)網(wǎng)領(lǐng)域廣泛使用的編程語言。Java 應(yīng)用的一些特性使其性能表現(xiàn)與提前編譯的原生應(yīng)用(例如 C 程序)大相徑庭。由于 Java 字節(jié)碼無法直接在 CPU 上執(zhí)行,因此通常運(yùn)行時在
    的頭像 發(fā)表于 11-05 11:25 ?623次閱讀
    Arm Neoverse CPU上大代碼量<b class='flag-5'>Java</b>應(yīng)用的性能測試

    Java效率提升指南:5個Java工具選型建議及Perforce JRebel和XRebel介紹

    企業(yè)Java環(huán)境越來越復(fù)雜,真正的破局點(diǎn),可能不在“人”,而在于“工具”。5個實(shí)用建議,幫你理清Java工具的選型思路。
    的頭像 發(fā)表于 09-11 13:59 ?1223次閱讀
    <b class='flag-5'>Java</b>效率提升指南:5個<b class='flag-5'>Java</b>工具選型建議及Perforce JRebel和XRebel介紹

    EtherCAT運(yùn)動控制卡應(yīng)用開發(fā)教程之Java

    運(yùn)動控制卡的Java開發(fā)及DLL調(diào)用
    的頭像 發(fā)表于 06-13 14:29 ?793次閱讀
    EtherCAT運(yùn)動控制卡應(yīng)用開發(fā)教程之<b class='flag-5'>Java</b>

    STM32MP157d linux5.4.31升級到6.1.82無法啟動怎么解決?

    我以前一直使用linux5.4.31,只使用了TFA沒有optee uboot是2020版本。一直用得好好的 上個禮拜我想升級到6.1.82(主要想打RT linux patch, 看到STM有出
    發(fā)表于 06-10 07:31

    JDK8升級到21的問題集

    一、背景與挑戰(zhàn) 1. 升級動因 ?Oracle長期支持策略 ?現(xiàn)代特性需求:協(xié)程、模式匹配、ZGC等 ?安全性與性能的需求 ?AI新技術(shù)引入的版本要求 2. 項(xiàng)目情況 ?100+項(xiàng)目并行升級
    的頭像 發(fā)表于 06-06 16:49 ?751次閱讀

    STM32MP157d linux5.4.31升級到6.1.82無法啟動怎么解決?

    我以前一直使用linux5.4.31,只使用了TFA沒有optee uboot是2020版本。一直用得好好的 上個禮拜我想升級到6.1.82(主要想打RT linux patch, 看到STM有出
    發(fā)表于 06-06 06:42

    STM32MP157d linux5.4.31升級到6.1.82無法啟動怎么解決?

    我以前一直使用linux5.4.31,只使用了TFA沒有optee uboot是2020版本。一直用得好好的 上個禮拜我想升級到6.1.82(主要想打RT linux patch, 看到STM有出
    發(fā)表于 05-21 06:20

    Java開發(fā)者必備的效率工具——Perforce JRebel是什么?為什么很多Java開發(fā)者在用?

    Perforce JRebel是一款Java開發(fā)效率工具,旨在幫助java開發(fā)人員更快地編寫更好的應(yīng)用程序。JRebel可即時重新加載對代碼的修改,無需重啟或重新部署應(yīng)用程序,就能讓開發(fā)者即時看到代碼更改的效果,從而縮短開發(fā)、調(diào)試和測試周期,大大提升開發(fā)效率。
    的頭像 發(fā)表于 04-27 13:44 ?731次閱讀
    <b class='flag-5'>Java</b>開發(fā)者必備的效率工具——Perforce JRebel是什么?為什么很多<b class='flag-5'>Java</b>開發(fā)者在用?

    STM32MP157d linux5.4.31升級到6.1.82無法啟動的原因?

    我以前一直使用linux5.4.31,只使用了TFA沒有optee uboot是2020版本。一直用得好好的 上個禮拜我想升級到6.1.82(主要想打RT linux patch, 看到STM有出
    發(fā)表于 04-27 06:30

    Java Go:面向?qū)ο蟮木奕伺c云原生的輕騎兵

    Go 語言在 2009 年被 Google 推出,在創(chuàng)建之初便明確提出了“少即是多(Less is more)”的設(shè)計(jì)原則,強(qiáng)調(diào)“以工程效率為核心,用極簡規(guī)則解決復(fù)雜問題”。它與 Java 語言生態(tài)
    的頭像 發(fā)表于 04-25 11:13 ?583次閱讀

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

    6.12.1升級到6.13老是閃退,回到6.12.1又正常,問一下大家是什么原因?qū)е拢惺裁唇鉀Q辦法?
    發(fā)表于 03-11 08:13

    Java的SPI機(jī)制詳解

    作者:京東物流 楊葦葦 1.SPI簡介 SPI(Service Provicer Interface)是Java語言提供的一種接口發(fā)現(xiàn)機(jī)制,用來實(shí)現(xiàn)接口和接口實(shí)現(xiàn)的解耦。簡單來說,就是系統(tǒng)只需要定義
    的頭像 發(fā)表于 03-05 11:35 ?1252次閱讀
    <b class='flag-5'>Java</b>的SPI機(jī)制詳解

    Java應(yīng)用OOM問題的排查過程

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