溫馨提示×

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

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

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

發(fā)布時(shí)間:2021-12-21 13:52:00 來源:億速云 閱讀:255 作者:iii 欄目:編程語(yǔ)言

這篇文章主要介紹“JVM內(nèi)存的結(jié)構(gòu)是怎樣的”,在日常操作中,相信很多人在JVM內(nèi)存的結(jié)構(gòu)是怎樣的問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JVM內(nèi)存的結(jié)構(gòu)是怎樣的”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

前言

所有的Java開發(fā)人員可能會(huì)遇到這樣的困惑?我該為堆內(nèi)存設(shè)置多大空間呢?OutOfMemoryError的異常到底涉及到運(yùn)行時(shí)數(shù)據(jù)的哪塊區(qū)域?該怎么解決呢?

其實(shí)如果你經(jīng)常解決服務(wù)器性能問題,那么這些問題就會(huì)變的非常常見,了解JVM內(nèi)存也是為了服務(wù)器出現(xiàn)性能問題的時(shí)候可以快速的了解那塊的內(nèi)存區(qū)域出現(xiàn)問題,以便于快速的解決生產(chǎn)故障。

先看一張圖,這張圖能很清晰的說明JVM內(nèi)存結(jié)構(gòu)布局。

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

JVM內(nèi)存結(jié)構(gòu)主要有三大塊:堆內(nèi)存、方法區(qū)和棧。堆內(nèi)存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內(nèi)存又被分成三部分,Eden空間、From Survivor空間、To Survivor空間,默認(rèn)情況下年輕代按照8:1:1的比例來分配;

方法區(qū)存儲(chǔ)類信息、常量、靜態(tài)變量等數(shù)據(jù),是線程共享的區(qū)域,為與Java堆區(qū)分,方法區(qū)還有一個(gè)別名Non-Heap(非堆);棧又分為java虛擬機(jī)棧和本地方法棧主要用于方法的執(zhí)行。

在通過一張圖來了解如何通過參數(shù)來控制各區(qū)域的內(nèi)存大小

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

控制參數(shù)

  • -Xms設(shè)置堆的最小空間大小。

  • -Xmx設(shè)置堆的最大空間大小。

  • -XX:NewSize設(shè)置新生代最小空間大小。

  • -XX:MaxNewSize設(shè)置新生代最大空間大小。

  • -XX:PermSize設(shè)置永久代最小空間大小。

  • -XX:MaxPermSize設(shè)置永久代最大空間大小。

  • -Xss設(shè)置每個(gè)線程的堆棧大小。

沒有直接設(shè)置老年代的參數(shù),但是可以設(shè)置堆空間大小和新生代空間大小兩個(gè)參數(shù)來間接控制。

老年代空間大小=堆空間大小-年輕代大空間大小

從更高的一個(gè)維度再次來看JVM和系統(tǒng)調(diào)用之間的關(guān)系

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

方法區(qū)和對(duì)是所有線程共享的內(nèi)存區(qū)域;而java棧、本地方法棧和程序員計(jì)數(shù)器是運(yùn)行是線程私有的內(nèi)存區(qū)域。

下面我們?cè)敿?xì)介紹每個(gè)區(qū)域的作用

Java堆(Heap)

對(duì)于大多數(shù)應(yīng)用來說,Java堆(Java Heap)是Java虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存。

Java堆是垃圾收集器管理的主要區(qū)域,因此很多時(shí)候也被稱做“GC堆”。如果從內(nèi)存回收的角度看,由于現(xiàn)在收集器基本都是采用的分代收集算法,所以Java堆中還可以細(xì)分為:新生代和老年代;再細(xì)致一點(diǎn)的有Eden空間、From Survivor空間、To Survivor空間等。

根據(jù)Java虛擬機(jī)規(guī)范的規(guī)定,Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可,就像我們的磁盤空間一樣。在實(shí)現(xiàn)時(shí),既可以實(shí)現(xiàn)成固定大小的,也可以是可擴(kuò)展的,不過當(dāng)前主流的虛擬機(jī)都是按照可擴(kuò)展來實(shí)現(xiàn)的(通過-Xmx和-Xms控制)。

如果在堆中沒有內(nèi)存完成實(shí)例分配,并且堆也無法再擴(kuò)展時(shí),將會(huì)拋出OutOfMemoryError異常。

方法區(qū)(Method Area)

方法區(qū)(Method Area)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。雖然Java虛擬機(jī)規(guī)范把方法區(qū)描述為堆的一個(gè)邏輯部分,但是它卻有一個(gè)別名叫做Non-Heap(非堆),目的應(yīng)該是與Java堆區(qū)分開來。

對(duì)于習(xí)慣在HotSpot虛擬機(jī)上開發(fā)和部署程序的開發(fā)者來說,很多人愿意把方法區(qū)稱為“永久代”(Permanent Generation),本質(zhì)上兩者并不等價(jià),僅僅是因?yàn)镠otSpot虛擬機(jī)的設(shè)計(jì)團(tuán)隊(duì)選擇把GC分代收集擴(kuò)展至方法區(qū),或者說使用永久代來實(shí)現(xiàn)方法區(qū)而已。

Java虛擬機(jī)規(guī)范對(duì)這個(gè)區(qū)域的限制非常寬松,除了和Java堆一樣不需要連續(xù)的內(nèi)存和可以選擇固定大小或者可擴(kuò)展外,還可以選擇不實(shí)現(xiàn)垃圾收集。相對(duì)而言,垃圾收集行為在這個(gè)區(qū)域是比較少出現(xiàn)的,但并非數(shù)據(jù)進(jìn)入了方法區(qū)就如永久代的名字一樣“永久”存在了。這個(gè)區(qū)域的內(nèi)存回收目標(biāo)主要是針對(duì)常量池的回收和對(duì)類型的卸載,一般來說這個(gè)區(qū)域的回收“成績(jī)”比較難以令人滿意,尤其是類型的卸載,條件相當(dāng)苛刻,但是這部分區(qū)域的回收確實(shí)是有必要的。

根據(jù)Java虛擬機(jī)規(guī)范的規(guī)定,當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時(shí),將拋出OutOfMemoryError異常。

方法區(qū)有時(shí)被稱為持久代(PermGen)。

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

所有的對(duì)象在實(shí)例化后的整個(gè)運(yùn)行周期內(nèi),都被存放在堆內(nèi)存中。堆內(nèi)存又被劃分成不同的部分:伊甸區(qū)(Eden),幸存者區(qū)域(Survivor Sapce),老年代(Old Generation Space)。

方法的執(zhí)行都是伴隨著線程的。原始類型的本地變量以及引用都存放在線程棧中。而引用關(guān)聯(lián)的對(duì)象比如String,都存在在堆中。為了更好的理解上面這段話,我們可以看一個(gè)例子:

import java.text.SimpleDateFormat;import java.util.Date;import org.apache.log4j.Logger;
 public class HelloWorld {
    private static Logger LOGGER = Logger.getLogger(HelloWorld.class.getName());
    public void sayHello(String message) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.YYYY");
        String today = formatter.format(new Date());
        LOGGER.info(today + ": " + message);
    }}

這段程序的數(shù)據(jù)在內(nèi)存中的存放如下:

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

通過JConsole工具可以查看運(yùn)行中的Java程序(比如Eclipse)的一些信息:堆內(nèi)存的分配,線程的數(shù)量以及加載的類的個(gè)數(shù);

JVM內(nèi)存的結(jié)構(gòu)是怎樣的

程序計(jì)數(shù)器(Program Counter Register)

程序計(jì)數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在虛擬機(jī)的概念模型里(僅是概念模型,各種虛擬機(jī)可能會(huì)通過一些更高效的方式去實(shí)現(xiàn)),字節(jié)碼解釋器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來完成。

由于Java虛擬機(jī)的多線程是通過線程輪流切換并分配處理器執(zhí)行時(shí)間的方式來實(shí)現(xiàn)的,在任何一個(gè)確定的時(shí)刻,一個(gè)處理器(對(duì)于多核處理器來說是一個(gè)內(nèi)核)只會(huì)執(zhí)行一條線程中的指令。因此,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各條線程之間的計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ),我們稱這類內(nèi)存區(qū)域?yàn)椤熬€程私有”的內(nèi)存。

如果線程正在執(zhí)行的是一個(gè)Java方法,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址;如果正在執(zhí)行的是Natvie方法,這個(gè)計(jì)數(shù)器值則為空(Undefined)。

此內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域。

JVM棧(JVM Stacks)

與程序計(jì)數(shù)器一樣,Java虛擬機(jī)棧(Java Virtual Machine Stacks)也是線程私有的,它的生命周期與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作棧、動(dòng)態(tài)鏈接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完成的過程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程。

局部變量表存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對(duì)象引用(reference類型,它不等同于對(duì)象本身,根據(jù)不同的虛擬機(jī)實(shí)現(xiàn),它可能是一個(gè)指向?qū)ο笃鹗嫉刂返囊弥羔槪部赡苤赶蛞粋€(gè)代表對(duì)象的句柄或者其他與此對(duì)象相關(guān)的位置)和returnAddress類型(指向了一條字節(jié)碼指令的地址)。

其中64位長(zhǎng)度的long和double類型的數(shù)據(jù)會(huì)占用2個(gè)局部變量空間(Slot),其余的數(shù)據(jù)類型只占用1個(gè)。局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí),這個(gè)方法需要在幀中分配多大的局部變量空間是完全確定的,在方法運(yùn)行期間不會(huì)改變局部變量表的大小。

在Java虛擬機(jī)規(guī)范中,對(duì)這個(gè)區(qū)域規(guī)定了兩種異常狀況:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverflowError異常;如果虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展(當(dāng)前大部分的Java虛擬機(jī)都可動(dòng)態(tài)擴(kuò)展,只不過Java虛擬機(jī)規(guī)范中也允許固定長(zhǎng)度的虛擬機(jī)棧),當(dāng)擴(kuò)展時(shí)無法申請(qǐng)到足夠的內(nèi)存時(shí)會(huì)拋出OutOfMemoryError異常。

本地方法棧(Native Method Stacks)

本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。虛擬機(jī)規(guī)范中對(duì)本地方法棧中的方法使用的語(yǔ)言、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒有強(qiáng)制規(guī)定,因此具體的虛擬機(jī)可以自由實(shí)現(xiàn)它。甚至有的虛擬機(jī)(譬如Sun HotSpot虛擬機(jī))直接就把本地方法棧和虛擬機(jī)棧合二為一。與虛擬機(jī)棧一樣,本地方法棧區(qū)域也會(huì)拋出StackOverflowError和OutOfMemoryError異常。

哪兒的OutOfMemoryError

對(duì)內(nèi)存結(jié)構(gòu)清晰的認(rèn)識(shí)同樣可以幫助理解不同OutOfMemoryErrors:

Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space

原因:對(duì)象不能被分配到堆內(nèi)存中

Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space

原因:類或者方法不能被加載到持久代。它可能出現(xiàn)在一個(gè)程序加載很多類的時(shí)候,比如引用了很多第三方的庫(kù);

Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit

原因:創(chuàng)建的數(shù)組大于堆內(nèi)存的空間

Exception in thread “main”: java.lang.OutOfMemoryError: requestbytes for. Out of swap space?原因:分配本地分配失敗。JNI、本地庫(kù)或者Java虛擬機(jī)都會(huì)從本地堆中分配內(nèi)存空間。Exception in thread “main”: java.lang.OutOfMemoryError:(Native method)原因:同樣是本地方法內(nèi)存分配失敗,只不過是JNI或者本地方法或者Java虛擬機(jī)發(fā)現(xiàn)JDK8-廢棄永久代(PermGen)迎來元空間(Metaspace)1.背景2.為什么廢棄永久代(PermGen)3.深入理解元空間(Metaspace)4.總結(jié)========正文分割線=====一、背景1.1 永久代(PermGen)在哪里?根據(jù),hotspot jvm結(jié)構(gòu)如下(虛擬機(jī)棧和本地方法棧合一起了):上圖引自網(wǎng)絡(luò),但有個(gè)問題:方法區(qū)和heap堆都是線程共享的內(nèi)存區(qū)域。關(guān)于方法區(qū)和永久代:在HotSpot JVM中,這次討論的永久代,就是上圖的方法區(qū)(JVM規(guī)范中稱為方法區(qū))。《Java虛擬機(jī)規(guī)范》只是規(guī)定了有方法區(qū)這么個(gè)概念和它的作用,并沒有規(guī)定如何去實(shí)現(xiàn)它。在其他JVM上不存在永久代。1.2 JDK8永久代的廢棄JDK8 永久代變化如下圖:1.新生代:Eden+From Survivor+To Survivor2.老年代:OldGen3.永久代(方法區(qū)的實(shí)現(xiàn)) : PermGen——->替換為Metaspace(本地內(nèi)存中)二、為什么廢棄永久代(PermGen)2.1 官方說明參照J(rèn)EP122:
http://openjdk.java.net/jeps/122,原文截取:MotivationThis is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.即:移除永久代是為融合HotSpot JVM與 JRockit VM而做出的努力,因?yàn)镴Rockit沒有永久代,不需要配置永久代。2.2 現(xiàn)實(shí)使用中易出問題由于永久代內(nèi)存經(jīng)常不夠用或發(fā)生內(nèi)存泄露,爆出異常java.lang.OutOfMemoryError: PermGen其實(shí)在JDK7時(shí)就已經(jīng)逐步把永久代的內(nèi)容移動(dòng)到其他區(qū)域了,比如移動(dòng)到native區(qū),移動(dòng)到堆區(qū)等,而JDK8則是則是廢除了永久代,改用元數(shù)據(jù)。三、深入理解元空間(Metaspace)3.1元空間的內(nèi)存大小元空間是方法區(qū)的在HotSpot jvm 中的實(shí)現(xiàn),方法區(qū)主要用于存儲(chǔ)類的信息、常量池、方法數(shù)據(jù)、方法代碼等。方法區(qū)邏輯上屬于堆的一部分,但是為了與堆進(jìn)行區(qū)分,通常又叫“非堆”。元空間的本質(zhì)和永久代類似,都是對(duì)JVM規(guī)范中方法區(qū)的實(shí)現(xiàn)。不過元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機(jī)中,而是使用本地內(nèi)存。,理論上取決于32位/64位系統(tǒng)可虛擬的內(nèi)存大小??梢娨膊皇菬o限制的,需要配置參數(shù)。3.2常用配置參數(shù)1.MetaspaceSize初始化的Metaspace大小,控制元空間發(fā)生GC的閾值。GC后,動(dòng)態(tài)增加或降低MetaspaceSize。在默認(rèn)情況下,這個(gè)值大小根據(jù)不同的平臺(tái)在12M到20M浮動(dòng)。使用
Java -XX:+PrintFlagsInitial命令查看本機(jī)的初始化參數(shù)2.MaxMetaspaceSize限制Metaspace增長(zhǎng)的上限,防止因?yàn)槟承┣闆r導(dǎo)致Metaspace無限的使用本地內(nèi)存,影響到其他程序。在本機(jī)上該參數(shù)的默認(rèn)值為4294967295B(大約4096MB)。3.MinMetaspaceFreeRatio當(dāng)進(jìn)行過Metaspace GC之后,會(huì)計(jì)算當(dāng)前Metaspace的空閑空間比,如果空閑比小于這個(gè)參數(shù)(即實(shí)際非空閑占比過大,內(nèi)存不夠用),那么虛擬機(jī)將增長(zhǎng)Metaspace的大小。默認(rèn)值為40,也就是40%。設(shè)置該參數(shù)可以控制Metaspace的增長(zhǎng)的速度,太小的值會(huì)導(dǎo)致Metaspace增長(zhǎng)的緩慢,Metaspace的使用逐漸趨于飽和,可能會(huì)影響之后類的加載。而太大的值會(huì)導(dǎo)致Metaspace增長(zhǎng)的過快,浪費(fèi)內(nèi)存。4.MaxMetasaceFreeRatio當(dāng)進(jìn)行過Metaspace GC之后, 會(huì)計(jì)算當(dāng)前Metaspace的空閑空間比,如果空閑比大于這個(gè)參數(shù),那么虛擬機(jī)會(huì)釋放Metaspace的部分空間。默認(rèn)值為70,也就是70%。5.MaxMetaspaceExpansionMetaspace增長(zhǎng)時(shí)的最大幅度。在本機(jī)上該參數(shù)的默認(rèn)值為5452592B(大約為5MB)。6.MinMetaspaceExpansionMetaspace增長(zhǎng)時(shí)的最小幅度。在本機(jī)上該參數(shù)的默認(rèn)值為340784B(大約330KB為)。3.3測(cè)試并追蹤元空間大小3.3.1.測(cè)試字符串常量 1 public class StringOomMock {
 2     static String  base = "string";
 3     
 4     public static void main(String[] args) {
 5         Listlist = new ArrayList();
 6         for (int i=0;i< Integer.MAX_VALUE;i++){
 7             String str = base + base;
 8             base = str;
 9             list.add(str.intern());
10         }
11     }
12 }在eclipse中選中類—》run configuration—>java application—》new 參數(shù)如下:由于設(shè)定了最大內(nèi)存20M,很快就溢出,如下圖:可見在jdk8中:1.字符串常量由永久代轉(zhuǎn)移到堆中。2.持久代已不存在,PermSize MaxPermSize參數(shù)已移除。(看圖中最后兩行)3.3.2.測(cè)試元空間溢出根據(jù)定義,我們以加載類來測(cè)試元空間溢出,代碼如下: 1 package jdk8;
 2 
 3 import java.io.File;
 4 import java.lang.management.ClassLoadingMXBean;
 5 import java.lang.management.ManagementFactory;
 6 import java.net.URL;
 7 import java.net.URLClassLoader;
 8 import java.util.ArrayList;
 9 import java.util.List;
10 
11 /**
12  * 
13  * @ClassName:OOMTest
14  * @Description:模擬類加載溢出(元空間oom)
15  * @author diandian.zhang
16  * @date 2017年4月27日上午9:45:40
17  */
18 public class OOMTest {  
19     public static void main(String[] args) {  
20         try {  
21             //準(zhǔn)備url  
22             URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL();  
23             URL[] urls = {url};  
24             //獲取有關(guān)類型加載的JMX接口  
25             ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();  
26             //用于緩存類加載器  
27             ListclassLoaders = new ArrayList();  
28             while (true) {  
29                 //加載類型并緩存類加載器實(shí)例  
30                 ClassLoader classLoader = new URLClassLoader(urls);  
31                 classLoaders.add(classLoader);  
32                 classLoader.loadClass("ClassA");  
33                 //顯示數(shù)量信息(共加載過的類型數(shù)目,當(dāng)前還有效的類型數(shù)目,已經(jīng)被卸載的類型數(shù)目)  
34                 System.out.println("total: " + loadingBean.getTotalLoadedClassCount());  
35                 System.out.println("active: " + loadingBean.getLoadedClassCount());  
36                 System.out.println("unloaded: " + loadingBean.getUnloadedClassCount());  
37             }  
38         } catch (Exception e) {  
39             e.printStackTrace();  
40         }  
41     }  
42 }為了快速溢出,設(shè)置參數(shù):-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m,運(yùn)行結(jié)果如下:上圖證實(shí)了,我們的JDK8中類加載(方法區(qū)的功能)已經(jīng)不在永久代PerGem中了,而是Metaspace中??梢耘浜螶VisualVM來看,更直觀一些。四、總結(jié)本文講解了元空間(Metaspace)的由來和本質(zhì),常用配置,以及監(jiān)控測(cè)試。元空間的大小是動(dòng)態(tài)變更的,但不是無限大的,最好也時(shí)常關(guān)注一下大小,以免影響服務(wù)器內(nèi)存。參考文章https://segmentfault.com/a/1190000009707894https://www.cnblogs.com/hysum/p/7100874.htmlhttp://c.biancheng.net/view/939.htmlhttps://www.runoob.com/https://blog.csdn.net/android_hl/article/details/53228348

到此,關(guān)于“JVM內(nèi)存的結(jié)構(gòu)是怎樣的”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(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