溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何合理的規(guī)劃一次JVM性能調(diào)優(yōu)

發(fā)布時(shí)間:2021-10-21 10:37:49 來(lái)源:億速云 閱讀:125 作者:柒染 欄目:大數(shù)據(jù)

今天就跟大家聊聊有關(guān)如何合理的規(guī)劃一次JVM性能調(diào)優(yōu),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

摘要: JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動(dòng)全身,需要全盤(pán)考慮各方面的影響,那么如何進(jìn)行一次優(yōu)雅的調(diào)優(yōu),提升應(yīng)用的性能? 

JVM性能調(diào)優(yōu)涉及到方方面面的取舍,往往是牽一發(fā)而動(dòng)全身,需要全盤(pán)考慮各方面的影響。但也有一些基礎(chǔ)的理論和原則,理解這些理論并遵循這些原則會(huì)讓你的性能調(diào)優(yōu)任務(wù)將會(huì)更加輕松。為了更好的理解本篇所介紹的內(nèi)容。你需要已經(jīng)了解和遵循以下內(nèi)容:

1、已了解jvm 垃圾收集器

2、已了解jvm 性能監(jiān)控常用工具

3、能夠讀懂gc日志

4、確信不為了調(diào)優(yōu)而調(diào)優(yōu),jvm調(diào)優(yōu)不能解決一切性能問(wèn)題

這些內(nèi)容在之前的兩篇文章已經(jīng)介紹過(guò)了,如果有不了解的可以去點(diǎn)擊上述連接進(jìn)行回顧,如果對(duì)這些不了解不建議讀本篇文章。

一、性能調(diào)優(yōu)的層次

為了提升系統(tǒng)性能,我們需要對(duì)系統(tǒng)的各個(gè)角度和層次來(lái)進(jìn)行優(yōu)化,以下是需要優(yōu)化的幾個(gè)層次。

從上面我們可以看到,除了jvm調(diào)優(yōu)以外,還有其他幾個(gè)層面需要來(lái)處理,所以針對(duì)系統(tǒng)的調(diào)優(yōu)不是只有jvm調(diào)優(yōu)一項(xiàng),而是需要針對(duì)系統(tǒng)來(lái)整體調(diào)優(yōu),才能提升系統(tǒng)的性能。本篇只針對(duì)jvm調(diào)優(yōu)來(lái)講解,其他幾個(gè)方面,后續(xù)再介紹。

在進(jìn)行jvm調(diào)優(yōu)之前,我們假設(shè)項(xiàng)目的架構(gòu)調(diào)優(yōu)和代碼調(diào)優(yōu)已經(jīng)進(jìn)行過(guò)或者是針對(duì)當(dāng)前項(xiàng)目是最優(yōu)的。這兩個(gè)是jvm調(diào)優(yōu)的基礎(chǔ),并且架構(gòu)調(diào)優(yōu)是對(duì)系統(tǒng)影響最大的 ,我們不能指望一個(gè)系統(tǒng)架構(gòu)有缺陷或者代碼層次優(yōu)化沒(méi)有窮盡的應(yīng)用,通過(guò)jvm調(diào)優(yōu)令其達(dá)到一個(gè)質(zhì)的飛躍,這是不可能的。

另外,在調(diào)優(yōu)之前,必須得有明確的性能優(yōu)化目標(biāo), 然后找到其性能瓶頸。之后針對(duì)瓶頸的優(yōu)化,還需要對(duì)應(yīng)用進(jìn)行壓力和基準(zhǔn)測(cè)試,通過(guò)各種監(jiān)控和統(tǒng)計(jì)工具,確認(rèn)調(diào)優(yōu)后的應(yīng)用是否已經(jīng)達(dá)到相關(guān)目標(biāo)。

二、jvm調(diào)優(yōu)流程

調(diào)優(yōu)的最終目的都是為了令應(yīng)用程序使用最小的硬件消耗來(lái)承載更大的吞吐。jvm的調(diào)優(yōu)也不例外,jvm調(diào)優(yōu)主要是針對(duì)垃圾收集器的收集性能優(yōu)化,令運(yùn)行在虛擬機(jī)上的應(yīng)用能夠使用更少的內(nèi)存以及延遲獲取更大的吞吐量。當(dāng)然這里的最少是最優(yōu)的選擇,而不是越少越好。

1、性能定義

要查找和評(píng)估器性能瓶頸,首先要知道性能定義,對(duì)于jvm調(diào)優(yōu)來(lái)說(shuō),我們需要知道以下三個(gè)定義屬性,依作為評(píng)估基礎(chǔ):

吞吐量:重要指標(biāo)之一,是指不考慮垃圾收集引起的停頓時(shí)間或內(nèi)存消耗,垃圾收集器能支撐應(yīng)用達(dá)到的最高性能指標(biāo)。 
延遲:其度量標(biāo)準(zhǔn)是縮短由于垃圾啊收集引起的停頓時(shí)間或者完全消除因垃圾收集所引起的停頓,避免應(yīng)用運(yùn)行時(shí)發(fā)生抖動(dòng)。 
內(nèi)存占用:垃圾收集器流暢運(yùn)行所需要 的內(nèi)存數(shù)量。 
這三個(gè)屬性中,其中一個(gè)任何一個(gè)屬性性能的提高,幾乎都是以另外一個(gè)或者兩個(gè)屬性性能的損失作代價(jià),不可兼得,具體某一個(gè)屬性或者兩個(gè)屬性的性能對(duì)應(yīng)用來(lái)說(shuō)比較重要,要基于應(yīng)用的業(yè)務(wù)需求來(lái)確定。

2、性能調(diào)優(yōu)原則

在調(diào)優(yōu)過(guò)程中,我們應(yīng)該謹(jǐn)記以下3個(gè)原則,以便幫助我們更輕松的完成垃圾收集的調(diào)優(yōu),從而達(dá)到應(yīng)用程序的性能要求。

  1. MinorGC回收原則: 每次minor GC 都要盡可能多的收集垃圾對(duì)象。以減少應(yīng)用程序發(fā)生Full GC的頻率。

  2. GC內(nèi)存最大化原則:處理吞吐量和延遲問(wèn)題時(shí)候,垃圾處理器能使用的內(nèi)存越大,垃圾收集的效果越好,應(yīng)用程序也會(huì)越來(lái)越流暢。

  3. GC調(diào)優(yōu)3選2原則: 在性能屬性里面,吞吐量、延遲、內(nèi)存占用,我們只能選擇其中兩個(gè)進(jìn)行調(diào)優(yōu),不可三者兼得。

3、性能調(diào)優(yōu)流程

以上就是對(duì)應(yīng)用程序進(jìn)行jvm調(diào)優(yōu)的基本流程,我們可以看到,jvm調(diào)優(yōu)是根據(jù)性能測(cè)試結(jié)果不斷優(yōu)化配置而多次迭代的過(guò)程。在達(dá)到每一個(gè)系統(tǒng)需求指標(biāo)之前,之前的每個(gè)步驟都有可能經(jīng)歷多次迭代。有時(shí)候?yàn)榱诉_(dá)到某一方面的指標(biāo),有可能需要對(duì)之前的參數(shù)進(jìn)行多次調(diào)整,進(jìn)而需要把之前的所有步驟重新測(cè)試一遍。

另外調(diào)優(yōu)一般是從滿足程序的內(nèi)存使用需求開(kāi)始的,之后是時(shí)間延遲的要求,最后才是吞吐量的要求,要基于這個(gè)步驟來(lái)不斷優(yōu)化,每一個(gè)步驟都是進(jìn)行下一步的基礎(chǔ),不可逆行之。以下我們針對(duì)每個(gè)步驟進(jìn)行詳細(xì)的示例講解。

在JVM的運(yùn)行模式方面,我們直接選擇server模式,這也是jdk1.6以后官方推薦的模式。

在垃圾收集器方面,我們直接采用了jdk1.6-1.8 中默認(rèn)的parallel收集器(新生代采用parallelGC,老生代采用parallelOldGC)。

三、確定內(nèi)存占用

在確定內(nèi)存占用之前,我們需要知道兩個(gè)知識(shí)點(diǎn):

應(yīng)用程序的運(yùn)行階段 
jvm內(nèi)存分配

1、運(yùn)行階段

應(yīng)用程序的運(yùn)行階段,我可以劃分為以下三個(gè)階段:

1、初始化階段 : jvm加載應(yīng)用程序,初始化應(yīng)用程序的主要模塊和數(shù)據(jù)。

2、穩(wěn)定階段:應(yīng)用在此時(shí)運(yùn)行了大多數(shù)時(shí)間,經(jīng)歷過(guò)壓力測(cè)試的之后,各項(xiàng)性能參數(shù)呈穩(wěn)定狀態(tài)。核心函數(shù)被執(zhí)行,已經(jīng)被jit編譯預(yù)熱過(guò)。

3、總結(jié)階段:最后的總結(jié)階段,進(jìn)行一些基準(zhǔn)測(cè)試,生成響應(yīng)的策報(bào)告。這個(gè)階段我們可以不關(guān)注。

確定內(nèi)存占用以及活躍數(shù)據(jù)的大小,我們應(yīng)該是在程序的穩(wěn)定階段來(lái)進(jìn)行確定,而不是在項(xiàng)目起初階段來(lái)進(jìn)行確定,如何確定,我們先看以下jvm的內(nèi)存分配。

2、jvm內(nèi)存分配&參數(shù)

jvm堆中主要的空間,就是以上新生代、老生代、永久代組成,整個(gè)堆大小=新生代大小 + 老生代大小 + 永久代大小。 具體的對(duì)象提升方式,這里不再過(guò)多介紹了,我們看下一些jvm命令參數(shù),對(duì)堆大小的指定。如果不采用以下參數(shù)進(jìn)行指定的話,虛擬機(jī)會(huì)自動(dòng)選擇合適的值,同時(shí)也會(huì)基于系統(tǒng)的開(kāi)銷自動(dòng)調(diào)整。

分代 
參數(shù) 
描述 
堆大小 
-Xms 
初始堆大小,默認(rèn)為物理內(nèi)存的1/64(<1GB)

-Xmx 
最大堆大小,默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到 -Xms的最小限制 
新生代 
-XX:NewSize 
新生代空間大小初始值

-XX:MaxNewSize 
新生代空間大小最大值

-Xmn 
新生代空間大小,此處的大小是(eden+2 survivor space) 
永久代 
-XX:PermSize 
永久代空間的初始值&最小值

-XX:MaxPermSize 
永久代空間的最大值 
老年代 
老年代的空間大小會(huì)根據(jù)新生代的大小隱式設(shè)定

初始值=-Xmx減去-XX:NewSize的值

最小值=-Xmx值減去-XX:MaxNewSize的值

在設(shè)置的時(shí)候,如果關(guān)注性能開(kāi)銷的話,應(yīng)盡量把永久代的初始值與最大值設(shè)置為同一值,因?yàn)橛谰么拇笮≌{(diào)整需要進(jìn)行FullGC 才能實(shí)現(xiàn)。

3、計(jì)算活躍數(shù)據(jù)大小

計(jì)算活躍數(shù)據(jù)大小應(yīng)該遵循以下流程:

如前所述,活躍數(shù)據(jù)應(yīng)該是基于應(yīng)用程序穩(wěn)定階段時(shí),觀察長(zhǎng)期存活與對(duì)象在java堆中占用的空間大小。

計(jì)算活躍數(shù)據(jù)時(shí)應(yīng)該確保以下條件發(fā)生:

1.測(cè)試時(shí),啟動(dòng)參數(shù)采用jvm默認(rèn)參數(shù),不人為設(shè)置。

2.確保Full GC 發(fā)生時(shí),應(yīng)用程序正處于穩(wěn)定階段。

采用jvm默認(rèn)參數(shù)啟動(dòng),是為了觀察應(yīng)用程序在穩(wěn)定階段的所需要的內(nèi)存使用。

如何才算穩(wěn)定階段?

一定得需要產(chǎn)生足夠的壓力,找到應(yīng)用程序和生產(chǎn)環(huán)境高峰符合狀態(tài)類似的負(fù)荷,在此之后達(dá)到峰值之后,保持一個(gè)穩(wěn)定的狀態(tài),才算是一個(gè)穩(wěn)定階段。所以要達(dá)到穩(wěn)定階段,壓力測(cè)試是必不可少的,具體如何如何對(duì)應(yīng)用壓力測(cè)試,本篇不過(guò)多說(shuō)明,后期會(huì)有專門(mén)介紹的篇幅。

在確定了應(yīng)用出于穩(wěn)定階段的時(shí)候,要注意觀察應(yīng)用的GC日志,特別是Full GC 日志。

GC日志指令: -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:

GC日志是收集調(diào)優(yōu)所需信息的最好途徑,即便是在生產(chǎn)環(huán)境,也可以開(kāi)啟GC日志來(lái)定位問(wèn)題,開(kāi)啟GC日志對(duì)性能的影響極小,卻可以提供豐富數(shù)據(jù)。

必須得有FullGC 日志,如果沒(méi)有的話,可以采用監(jiān)控工具強(qiáng)制調(diào)用一次,或者采用以下命令,亦可以觸發(fā)

jmap -histo:live pid

在穩(wěn)定階段觸發(fā)了FullGC我們一般會(huì)拿到如下信息:

從以上gc日志中,我們大概可以分析到,在發(fā)生fullGC之時(shí),整個(gè)應(yīng)用的堆占用以及GC時(shí)間,當(dāng)然了,為了更加精確,應(yīng)該多收集幾次,獲取一個(gè)平均值?;蛘呤遣捎煤臅r(shí)最長(zhǎng)的一次FullGC來(lái)進(jìn)行估算。

在上圖中,fullGC之后,老年代空間占用在93168kb(約93MB),我們以此定為老年代空間的活躍數(shù)據(jù)。

其他堆空間的分配,基于以下規(guī)則來(lái)進(jìn)行。

空間 
命令參數(shù) 
建議擴(kuò)大倍數(shù) 
java heap 
-Xms和-Xmx 
3-4倍FullGC后的老年代空間占用 
永久代 
-XX:PermSize 
-XX:MaxPermSize 
1.2-1.5倍FullGc后的永久帶空間占用 
新生代 
-Xmn 
1-1.5倍FullGC之后的老年代空間占用 
老年代

2-3倍FullGC后的老年代空間占用 
基于以上規(guī)則和上圖中的FullGC信息,我們現(xiàn)在可以規(guī)劃的該應(yīng)用堆空間為:

java 堆空間: 373Mb (=老年代空間93168kb*4)

新生代空間:140Mb(=老年代空間93168kb*1.5)

永久代空間:5Mb(=永久代空間3135kb*1.5)

老年代空間: 233Mb=堆空間-新生代看空間=373Mb-140Mb

對(duì)應(yīng)的應(yīng)用啟動(dòng)參數(shù)應(yīng)該為:

java -Xms373m -Xmx373m -Xmn140m -XX:PermSize=5m -XX:MaxPermSize=5m

四、延遲調(diào)優(yōu)

在確定了應(yīng)用程序的活躍數(shù)據(jù)大小之后,我們需要再進(jìn)行延遲性調(diào)優(yōu),因?yàn)閷?duì)于此時(shí)堆內(nèi)存大小,延遲性需求無(wú)法達(dá)到應(yīng)用的需要,需要基于應(yīng)用的情況來(lái)進(jìn)行調(diào)試。

在這一步進(jìn)行期間,我們可能會(huì)再次優(yōu)化堆大小的配置,評(píng)估GC的持續(xù)時(shí)間和頻率、以及是否需要切換到不同的垃圾收集器上。

1、系統(tǒng)延遲需求

在調(diào)優(yōu)之前,我們需要知道系統(tǒng)的延遲需求是那些,以及對(duì)應(yīng)的延遲可調(diào)優(yōu)指標(biāo)是那些。

應(yīng)用程序可接受的平均停滯時(shí)間: 此時(shí)間與測(cè)量的Minor GC持續(xù)時(shí)間進(jìn)行比較。 
可接受的Minor GC頻率:Minor GC的頻率與可容忍的值進(jìn)行比較。 
可接受的最大停頓時(shí)間: 最大停頓時(shí)間與最差情況下FullGC的持續(xù)時(shí)間進(jìn)行比較。 
可接受的最大停頓發(fā)生的頻率:基本就是FullGC的頻率。 
以上中,平均停滯時(shí)間和最大停頓時(shí)間,對(duì)用戶體驗(yàn)最為重要,可以多關(guān)注。

基于以上的要求,我們需要統(tǒng)計(jì)以下數(shù)據(jù):

MinorGC的持續(xù)時(shí)間; 
統(tǒng)計(jì)MinorGC的次數(shù); 
FullGC的最差持續(xù)時(shí)間; 
最差情況下,F(xiàn)ullGC的頻率;

2、優(yōu)化新生代的大小

比如如上的gc日志中,我們可以看到Minor GC的平均持續(xù)時(shí)間=0.069秒,MinorGC 的頻率為0.389秒一次。

如果,我們系統(tǒng)的設(shè)置的平均停滯時(shí)間為50ms,當(dāng)前的69ms明顯是太長(zhǎng)了,就需要調(diào)整。

我們知道新生代空間越大,Minor GC的GC時(shí)間越長(zhǎng),頻率越低。

如果想減少其持續(xù)時(shí)長(zhǎng),就需要減少其空間大小。

如果想減小其頻率,就需要加大其空間大小。

為了降低改變新生代的大小對(duì)其他區(qū)域的最小影響。在改變新生代空間大小的時(shí)候,盡量保持老年代空間的大小。

比如此次減少了新生代空間10%的大小,應(yīng)該保持老年代和持代的大小不變化,第一步調(diào)優(yōu)后的參數(shù)如下變化:

java -Xms359m -Xmx359m -Xmn126m -XX:PermSize=5m -XX:MaxPermSize=5m

新生代的大小有140m變?yōu)?26,堆大小順應(yīng)變化,此時(shí)老年代是沒(méi)有變化的。

3、優(yōu)化老年代的大小

同上一步一樣,在優(yōu)化之前,也需要采集gc日志的數(shù)據(jù)。此次我們關(guān)注的是FullGC的持續(xù)時(shí)間和頻率。

上圖中,我們可以看到

FullGC 平均頻率 =5.8s

FullGC 平均持續(xù)時(shí)間=0.14s

(以上為了測(cè)試,真實(shí)項(xiàng)目的fullGC 沒(méi)有這么快)

如果沒(méi)有FullGC的日志,有辦法可以評(píng)估么?

我們可以通過(guò)對(duì)象提升率進(jìn)行計(jì)算。

對(duì)象提升率

比如上述中啟動(dòng)參數(shù)中,我們的老年代大小=233Mb。

那么需要多久才能填滿老年代中這233Mb的空閑空間取決于新生代到老年代的提升率。

每次提升老年代占用量=每次MinorGC 之后 java堆占用情況 減去 MinorGC后新生代的空間占用

對(duì)象提升率=平均值(每次提升老年代占用量) 除以 老年代空間

有了對(duì)象提升率,我們就可以算出填充滿老年代空間需要多少次minorGC,大概一次fullGC的時(shí)間就可以計(jì)算出來(lái)了。

比如:

上圖中:

第一次minor GC 之后,老年代空間:13740kb - 13732kb =8kb

第二次minor GC 之后,老年代空間:22394kb - 17905kb =4489kb

第三次minor GC 之后,老年代空間:34739kb - 17917kb =16822kb

第四次minor GC 之后,老年代空間:48143kb - 17913kb =30230kb

第五次minor GC 之后,老年代空間:62112kb - 17917kb =44195kb 
老年代每次minorGC提升率

4481kb 第二次和第一次minorGC之間

12333kb 第3次和第2次minorGC之間

13408kb 第4次和第3次minorGC之間

13965kb 第5次和第4次minorGC之間 
我們可以測(cè)算出:

每次minorGC 的平均提升為12211kb,約為12Mb

上圖中,平均minorGC的頻率為 213ms/次

提升率=12211kb/213ms=57kb/ms

老年代空間233Mb ,占滿大概需要233*1024/57=4185ms 約為4.185s。

FullGC的預(yù)期最差頻率時(shí)長(zhǎng)可以通過(guò)以上兩種方式估算出來(lái),可以調(diào)整老年代的大小來(lái)調(diào)整FullGC的頻率,當(dāng)然了,如果FullGC持續(xù)時(shí)間過(guò)長(zhǎng),無(wú)法達(dá)到應(yīng)用程序的最差延遲要求,就需要切換垃圾處理器了。具體如何切換,下篇再講,比如切換為CMS,針對(duì)CMS的調(diào)優(yōu)方式又有會(huì)細(xì)微的差別。

五、吞吐量調(diào)優(yōu)

經(jīng)過(guò)上述漫長(zhǎng) 調(diào)優(yōu)過(guò)程,最終來(lái)到了調(diào)優(yōu)的最后一步,這一步對(duì)上述的結(jié)果進(jìn)行吞吐量測(cè)試,并進(jìn)行微調(diào)。

吞吐量調(diào)優(yōu)主要是基于應(yīng)用程序的吞吐量要求而來(lái)的,應(yīng)用程序應(yīng)該有一個(gè)綜合的吞吐指標(biāo),這個(gè)指標(biāo)基于真?zhèn)€應(yīng)用的需求和測(cè)試而衍生出來(lái)的。當(dāng)有應(yīng)用程序的吞吐量達(dá)到或者超過(guò)預(yù)期的吞吐目標(biāo),整個(gè)調(diào)優(yōu)過(guò)程就可以圓滿結(jié)束了。

如果出現(xiàn)調(diào)優(yōu)后依然無(wú)法達(dá)到應(yīng)用程序的吞吐目標(biāo),需要重新回顧吞吐要求,評(píng)估當(dāng)前吞吐量和目標(biāo)差距是否巨大,如果在20%左右,可以修改參數(shù),加大內(nèi)存,再次從頭調(diào)試,如果巨大就需要從整個(gè)應(yīng)用層面來(lái)考慮,設(shè)計(jì)以及目標(biāo)是否一致了,重新評(píng)估吞吐目標(biāo)。

對(duì)于垃圾收集器來(lái)說(shuō),提升吞吐量的性能調(diào)優(yōu)的目標(biāo)就是就是盡可能避免或者很少發(fā)生FullGC 或者Stop-The-World壓縮式垃圾收集(CMS),因?yàn)檫@兩種方式都會(huì)造成應(yīng)用程序吞吐降低。盡量在MinorGC 階段回收更多的對(duì)象,避免對(duì)象提升過(guò)快到老年代。

六、最后

據(jù)Plumbr公司對(duì)特定垃圾收集器使用情況進(jìn)行了一次調(diào)查研究,研究數(shù)據(jù)使用了84936個(gè)案例。在明確指定垃圾收集器的13%的案例中,并發(fā)收集器(CMS)使用次數(shù)最多;但大多數(shù)案例沒(méi)有選擇最佳垃圾收集器。這個(gè)比例占用在87%左右。

JVM調(diào)優(yōu)是一個(gè)系統(tǒng)而又復(fù)雜的工作,目前jvm下的自動(dòng)調(diào)整已經(jīng)做的比較優(yōu)秀,基本的一些初始參數(shù)都可以保證一般的應(yīng)用跑的比較穩(wěn)定了,對(duì)部分團(tuán)隊(duì)來(lái)說(shuō),程序性能可能優(yōu)先級(jí)不高,默認(rèn)垃圾收集器已經(jīng)夠用了。調(diào)優(yōu)要基于自己的情況而來(lái)。

看完上述內(nèi)容,你們對(duì)如何合理的規(guī)劃一次JVM性能調(diào)優(yōu)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI