真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言程序所占用內(nèi)存 go 限制內(nèi)存

Go 語言內(nèi)存管理(三):逃逸分析

Go 語言較之 C 語言一個(gè)很大的優(yōu)勢(shì)就是自帶 GC 功能,可 GC 并不是沒有代價(jià)的。寫 C 語言的時(shí)候,在一個(gè)函數(shù)內(nèi)聲明的變量,在函數(shù)退出后會(huì)自動(dòng)釋放掉,因?yàn)檫@些變量分配在棧上。如果你期望變量的數(shù)據(jù)可以在函數(shù)退出后仍然能被訪問,就需要調(diào)用 malloc 方法在堆上申請(qǐng)內(nèi)存,如果程序不再需要這塊內(nèi)存了,再調(diào)用 free 方法釋放掉。Go 語言不需要你主動(dòng)調(diào)用 malloc 來分配堆空間,編譯器會(huì)自動(dòng)分析,找出需要 malloc 的變量,使用堆內(nèi)存。編譯器的這個(gè)分析過程就叫做逃逸分析。

射洪ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

所以你在一個(gè)函數(shù)中通過 dict := make(map[string]int) 創(chuàng)建一個(gè) map 變量,其背后的數(shù)據(jù)是放在??臻g上還是堆空間上,是不一定的。這要看編譯器分析的結(jié)果。

可逃逸分析并不是百分百準(zhǔn)確的,它有缺陷。有的時(shí)候你會(huì)發(fā)現(xiàn)有些變量其實(shí)在??臻g上分配完全沒問題的,但編譯后程序還是把這些數(shù)據(jù)放在了堆上。如果你了解 Go 語言編譯器逃逸分析的機(jī)制,在寫代碼的時(shí)候就可以有意識(shí)地繞開這些缺陷,使你的程序更高效。

Go 語言雖然在內(nèi)存管理方面降低了編程門檻,即使你不了解堆棧也能正常開發(fā),但如果你要在性能上較真的話,還是要掌握這些基礎(chǔ)知識(shí)。

這里不對(duì)堆內(nèi)存和棧內(nèi)存的區(qū)別做太多闡述。簡(jiǎn)單來說就是, 棧分配廉價(jià),堆分配昂貴。 ??臻g會(huì)隨著一個(gè)函數(shù)的結(jié)束自動(dòng)釋放,堆空間需要時(shí)間 GC 模塊不斷地跟蹤掃描回收。如果對(duì)這兩個(gè)概念有些迷糊,建議閱讀下面 2 個(gè)文章:

這里舉一個(gè)小例子,來對(duì)比下堆棧的差別:

stack 函數(shù)中的變量 i 在函數(shù)退出會(huì)自動(dòng)釋放;而 heap 函數(shù)返回的是對(duì)變量 i 的引用,也就是說 heap() 退出后,表示變量 i 還要能被訪問,它會(huì)自動(dòng)被分配到堆空間上。

他們編譯出來的代碼如下:

邏輯的復(fù)雜度不言而喻,從上面的匯編中可看到, heap() 函數(shù)調(diào)用了 runtime.newobject() 方法,它會(huì)調(diào)用 mallocgc 方法從 mcache 上申請(qǐng)內(nèi)存,申請(qǐng)的內(nèi)部邏輯前面文章已經(jīng)講述過。堆內(nèi)存分配不僅分配上邏輯比??臻g分配復(fù)雜,它最致命的是會(huì)帶來很大的管理成本,Go 語言要消耗很多的計(jì)算資源對(duì)其進(jìn)行標(biāo)記回收(也就是 GC 成本)。

Go 編輯器會(huì)自動(dòng)幫我們找出需要進(jìn)行動(dòng)態(tài)分配的變量,它是在編譯時(shí)追蹤一個(gè)變量的生命周期,如果能確認(rèn)一個(gè)數(shù)據(jù)只在函數(shù)空間內(nèi)訪問,不會(huì)被外部使用,則使用棧空間,否則就要使用堆空間。

我們?cè)? go build 編譯代碼時(shí),可使用 -gcflags '-m' 參數(shù)來查看逃逸分析日志。

以上面的兩個(gè)函數(shù)為例,編譯的日志輸出是:

日志中的 i escapes to heap 表示該變量數(shù)據(jù)逃逸到了堆上。

需要使用堆空間,所以逃逸,這沒什么可爭(zhēng)議的。但編譯器有時(shí)會(huì)將 不需要 使用堆空間的變量,也逃逸掉。這里是容易出現(xiàn)性能問題的大坑。網(wǎng)上有很多相關(guān)文章,列舉了一些導(dǎo)致逃逸情況,其實(shí)總結(jié)起來就一句話:

多級(jí)間接賦值容易導(dǎo)致逃逸 。

這里的多級(jí)間接指的是,對(duì)某個(gè)引用類對(duì)象中的引用類成員進(jìn)行賦值。Go 語言中的引用類數(shù)據(jù)類型有 func , interface , slice , map , chan , *Type(指針) 。

記住公式 Data.Field = Value ,如果 Data , Field 都是引用類的數(shù)據(jù)類型,則會(huì)導(dǎo)致 Value 逃逸。這里的等號(hào) = 不單單只賦值,也表示參數(shù)傳遞。

根據(jù)公式,我們假設(shè)一個(gè)變量 data 是以下幾種類型,相應(yīng)的可以得出結(jié)論:

下面給出一些實(shí)際的例子:

如果變量值是一個(gè)函數(shù),函數(shù)的參數(shù)又是引用類型,則傳遞給它的參數(shù)都會(huì)逃逸。

上例中 te 的類型是 func(*int) ,屬于引用類型,參數(shù) *int 也是引用類型,則調(diào)用 te(j) 形成了為 te 的參數(shù)(成員) *int 賦值的現(xiàn)象,即 te.i = j 會(huì)導(dǎo)致逃逸。代碼中其他幾種調(diào)用都沒有形成 多級(jí)間接賦值 情況。

同理,如果函數(shù)的參數(shù)類型是 slice , map 或 interface{} 都會(huì)導(dǎo)致參數(shù)逃逸。

匿名函數(shù)的調(diào)用也是一樣的,它本質(zhì)上也是一個(gè)函數(shù)變量。有興趣的可以自己測(cè)試一下。

只要使用了 Interface 類型(不是 interafce{} ),那么賦值給它的變量一定會(huì)逃逸。因?yàn)? interfaceVariable.Method() 先是間接的定位到它的實(shí)際值,再調(diào)用實(shí)際值的同名方法,執(zhí)行時(shí)實(shí)際值作為參數(shù)傳遞給方法。相當(dāng)于 interfaceVariable.Method.this = realValue

向 channel 中發(fā)送數(shù)據(jù),本質(zhì)上就是為 channel 內(nèi)部的成員賦值,就像給一個(gè) slice 中的某一項(xiàng)賦值一樣。所以 chan *Type , chan map[Type]Type , chan []Type , chan interface{} 類型都會(huì)導(dǎo)致發(fā)送到 channel 中的數(shù)據(jù)逃逸。

這本來也是情理之中的,發(fā)送給 channel 的數(shù)據(jù)是要與其他函數(shù)分享的,為了保證發(fā)送過去的指針依然可用,只能使用堆分配。

可變參數(shù)如 func(arg ...string) 實(shí)際與 func(arg []string) 是一樣的,會(huì)增加一層訪問路徑。這也是 fmt.Sprintf 總是會(huì)使參數(shù)逃逸的原因。

例子非常多,這里不能一一列舉,我們只需要記住分析方法就好,即,2 級(jí)或更多級(jí)的訪問賦值會(huì) 容易 導(dǎo)致數(shù)據(jù)逃逸。這里加上 容易 二字是因?yàn)殡S著語言的發(fā)展,相信這些問題會(huì)被慢慢解決,但現(xiàn)階段,這個(gè)可以作為我們分析逃逸現(xiàn)象的依據(jù)。

下面代碼中包含 2 種很常規(guī)的寫法,但他們卻有著很大的性能差距,建議自己想下為什么。

Benchmark 和 pprof 給出的結(jié)果:

熟悉堆棧概念可以讓我們更容易看透 Go 程序的性能問題,并進(jìn)行優(yōu)化。

多級(jí)間接賦值會(huì)導(dǎo)致 Go 編譯器出現(xiàn)不必要的逃逸,在一些情況下可能我們只需要修改一下數(shù)據(jù)結(jié)構(gòu)就會(huì)使性能有大幅提升。這也是很多人不推薦在 Go 中使用指針的原因,因?yàn)樗鼤?huì)增加一級(jí)訪問路徑,而 map , slice , interface{} 等類型是不可避免要用到的,為了減少不必要的逃逸,只能拿指針開刀了。

大多數(shù)情況下,性能優(yōu)化都會(huì)為程序帶來一定的復(fù)雜度。建議實(shí)際項(xiàng)目中還是怎么方便怎么寫,功能完成后通過性能分析找到瓶頸所在,再對(duì)局部進(jìn)行優(yōu)化。

Golang 1.14中內(nèi)存分配、清掃和內(nèi)存回收

Golang的內(nèi)存分配是由golang runtime完成,其內(nèi)存分配方案借鑒自tcmalloc。

主要特點(diǎn)就是

本文中的element指一定大小的內(nèi)存塊是內(nèi)存分配的概念,并為出現(xiàn)在golang runtime源碼中

本文講述x8664架構(gòu)下的內(nèi)存分配

Golang 內(nèi)存分配有下面幾個(gè)主要結(jié)構(gòu)

Tiny對(duì)象是指內(nèi)存尺寸小于16B的對(duì)象,這類對(duì)象的分配使用mcache的tiny區(qū)域進(jìn)行分配。當(dāng)tiny區(qū)域空間耗盡時(shí)刻,它會(huì)從mcache.alloc[tinySpanClass]指向的mspan中找到空閑的區(qū)域。當(dāng)然如果mcache中span空間也耗盡,它會(huì)觸發(fā)從mcentral補(bǔ)充mspan到mcache的流程。

小對(duì)象是指對(duì)象尺寸在(16B,32KB]之間的對(duì)象,這類對(duì)象的分配原則是:

1、首先根據(jù)對(duì)象尺寸將對(duì)象歸為某個(gè)SpanClass上,這個(gè)SpanClass上所有的element都是一個(gè)統(tǒng)一的尺寸。

2、從mcache.alloc[SpanClass]找到mspan,看看有無空閑的element,如果有分配成功。如果沒有繼續(xù)。

3、從mcentral.allocSpan[SpanClass]的nonempty和emtpy中找到合適的mspan,返回給mcache。如果沒有找到就進(jìn)入mcentral.grow()—mheap.alloc()分配新的mspan給mcentral。

大對(duì)象指尺寸超出32KB的對(duì)象,此時(shí)直接從mheap中分配,不會(huì)走mcache和mcentral,直接走mheap.alloc()分配一個(gè)SpanClass==0 的mspan表示這部分分配空間。

對(duì)于程序分配常用的tiny和小對(duì)象的分配,可以通過無鎖的mcache提升分配性能。mcache不足時(shí)刻會(huì)拿mcentral的鎖,然后從mcentral中充mspan 給mcache。大對(duì)象直接從mheap 中分配。

在x8664環(huán)境上,golang管理的有效的程序虛擬地址空間實(shí)質(zhì)上只有48位。在mheap中有一個(gè)pages pageAlloc成員用于管理golang堆內(nèi)存的地址空間。golang從os中申請(qǐng)地址空間給自己管理,地址空間申請(qǐng)下來以后,golang會(huì)將地址空間根據(jù)實(shí)際使用情況標(biāo)記為free或者alloc。如果地址空間被分配給mspan或大對(duì)象后,那么被標(biāo)記為alloc,反之就是free。

Golang認(rèn)為地址空間有以下4種狀態(tài):

Golang同時(shí)定義了下面幾個(gè)地址空間操作函數(shù):

在mheap結(jié)構(gòu)中,有一個(gè)名為pages成員,它用于golang 堆使用虛擬地址空間進(jìn)行管理。其類型為pageAlloc

pageAlloc 結(jié)構(gòu)表示的golang 堆的所有地址空間。其中最重要的成員有兩個(gè):

在golang的gc流程中會(huì)將未使用的對(duì)象標(biāo)記為未使用,但是這些對(duì)象所使用的地址空間并未交還給os。地址空間的申請(qǐng)和釋放都是以golang的page為單位(實(shí)際以chunk為單位)進(jìn)行的。sweep的最終結(jié)果只是將某個(gè)地址空間標(biāo)記可被分配,并未真正釋放地址空間給os,真正釋放是后文的scavenge過程。

在gc mark結(jié)束以后會(huì)使用sweep()去嘗試free一個(gè)span;在mheap.alloc 申請(qǐng)mspan時(shí)刻,也使用sweep去清掃一下。

清掃mspan主要涉及到下面函數(shù)

如上節(jié)所述,sweep只是將page標(biāo)記為可分配,但是并未把地址空間釋放;真正的地址空間釋放是scavenge過程。

真正的scavenge是由pageAlloc.scavenge()—sysUnused()將掃描到待釋放的chunk所表示的地址空間釋放掉(使用sysUnused()將地址空間還給os)

golang的scavenge過程有兩種:

嵌入式golang占用內(nèi)存高

嵌入式golang占用內(nèi)存高可能問題在于緩存。

清空日志后比較驚喜地發(fā)現(xiàn),內(nèi)存瞬間暴降至20M。

嵌入式系統(tǒng)由硬件和軟件組成.是能夠獨(dú)立進(jìn)行運(yùn)作的器件。其軟件內(nèi)容只包括軟件運(yùn)行環(huán)境及其操作系統(tǒng)。硬件內(nèi)容包括信號(hào)處理器、存儲(chǔ)器、通信模塊等在內(nèi)的多方面的內(nèi)容。相比于一般的計(jì)算機(jī)處理系統(tǒng)而言,嵌入式系統(tǒng)存在較大的差異性,它不能實(shí)現(xiàn)大容量的存儲(chǔ)功能,因?yàn)闆]有與之相匹配的大容量介質(zhì),大部分采用的存儲(chǔ)介質(zhì)有E-PROM、EEPROM等,軟件部分以API編程接口作為開發(fā)平臺(tái)的核心。嵌入式系統(tǒng)最核心的層次是中央處理單元部分,它包含運(yùn)算器和控制器模塊,在cpu的基礎(chǔ)上進(jìn)一步配上存儲(chǔ)器模塊、電源模塊、復(fù)位模塊等就構(gòu)成了通常所說的最小系統(tǒng)。由于技術(shù)的進(jìn)步,集成電路生產(chǎn)商通常會(huì)把許多外設(shè)做進(jìn)同一個(gè)集成電路中,這樣在使用上更加方便,這樣一個(gè)芯片通常稱之為微控制器。在微控制器的基礎(chǔ)上進(jìn)一步擴(kuò)展電源傳感與檢測(cè)、執(zhí)行器模塊以及配套軟件并構(gòu)成一個(gè)具有特定功能的完整單元,就稱之為一個(gè)嵌入式系統(tǒng)或嵌入式應(yīng)用。

(十一)golang 內(nèi)存分析

編寫過C語言程序的肯定知道通過malloc()方法動(dòng)態(tài)申請(qǐng)內(nèi)存,其中內(nèi)存分配器使用的是glibc提供的ptmalloc2。 除了glibc,業(yè)界比較出名的內(nèi)存分配器有Google的tcmalloc和Facebook的jemalloc。二者在避免內(nèi)存碎片和性能上均比glic有比較大的優(yōu)勢(shì),在多線程環(huán)境中效果更明顯。

Golang中也實(shí)現(xiàn)了內(nèi)存分配器,原理與tcmalloc類似,簡(jiǎn)單的說就是維護(hù)一塊大的全局內(nèi)存,每個(gè)線程(Golang中為P)維護(hù)一塊小的私有內(nèi)存,私有內(nèi)存不足再?gòu)娜稚暾?qǐng)。另外,內(nèi)存分配與GC(垃圾回收)關(guān)系密切,所以了解GC前有必要了解內(nèi)存分配的原理。

為了方便自主管理內(nèi)存,做法便是先向系統(tǒng)申請(qǐng)一塊內(nèi)存,然后將內(nèi)存切割成小塊,通過一定的內(nèi)存分配算法管理內(nèi)存。 以64位系統(tǒng)為例,Golang程序啟動(dòng)時(shí)會(huì)向系統(tǒng)申請(qǐng)的內(nèi)存如下圖所示:

預(yù)申請(qǐng)的內(nèi)存劃分為spans、bitmap、arena三部分。其中arena即為所謂的堆區(qū),應(yīng)用中需要的內(nèi)存從這里分配。其中spans和bitmap是為了管理arena區(qū)而存在的。

arena的大小為512G,為了方便管理把a(bǔ)rena區(qū)域劃分成一個(gè)個(gè)的page,每個(gè)page為8KB,一共有512GB/8KB個(gè)頁;

spans區(qū)域存放span的指針,每個(gè)指針對(duì)應(yīng)一個(gè)page,所以span區(qū)域的大小為(512GB/8KB)乘以指針大小8byte = 512M

bitmap區(qū)域大小也是通過arena計(jì)算出來,不過主要用于GC。

span是用于管理arena頁的關(guān)鍵數(shù)據(jù)結(jié)構(gòu),每個(gè)span中包含1個(gè)或多個(gè)連續(xù)頁,為了滿足小對(duì)象分配,span中的一頁會(huì)劃分更小的粒度,而對(duì)于大對(duì)象比如超過頁大小,則通過多頁實(shí)現(xiàn)。

根據(jù)對(duì)象大小,劃分了一系列class,每個(gè)class都代表一個(gè)固定大小的對(duì)象,以及每個(gè)span的大小。如下表所示:

上表中每列含義如下:

class: class ID,每個(gè)span結(jié)構(gòu)中都有一個(gè)class ID, 表示該span可處理的對(duì)象類型

bytes/obj:該class代表對(duì)象的字節(jié)數(shù)

bytes/span:每個(gè)span占用堆的字節(jié)數(shù),也即頁數(shù)乘以頁大小

objects: 每個(gè)span可分配的對(duì)象個(gè)數(shù),也即(bytes/spans)/(bytes/obj)waste

bytes: 每個(gè)span產(chǎn)生的內(nèi)存碎片,也即(bytes/spans)%(bytes/obj)上表可見最大的對(duì)象是32K大小,超過32K大小的由特殊的class表示,該class ID為0,每個(gè)class只包含一個(gè)對(duì)象。

span是內(nèi)存管理的基本單位,每個(gè)span用于管理特定的class對(duì)象, 跟據(jù)對(duì)象大小,span將一個(gè)或多個(gè)頁拆分成多個(gè)塊進(jìn)行管理。src/runtime/mheap.go:mspan定義了其數(shù)據(jù)結(jié)構(gòu):

以class 10為例,span和管理的內(nèi)存如下圖所示:

spanclass為10,參照class表可得出npages=1,nelems=56,elemsize為144。其中startAddr是在span初始化時(shí)就指定了某個(gè)頁的地址。allocBits指向一個(gè)位圖,每位代表一個(gè)塊是否被分配,本例中有兩個(gè)塊已經(jīng)被分配,其allocCount也為2。next和prev用于將多個(gè)span鏈接起來,這有利于管理多個(gè)span,接下來會(huì)進(jìn)行說明。

有了管理內(nèi)存的基本單位span,還要有個(gè)數(shù)據(jù)結(jié)構(gòu)來管理span,這個(gè)數(shù)據(jù)結(jié)構(gòu)叫mcentral,各線程需要內(nèi)存時(shí)從mcentral管理的span中申請(qǐng)內(nèi)存,為了避免多線程申請(qǐng)內(nèi)存時(shí)不斷的加鎖,Golang為每個(gè)線程分配了span的緩存,這個(gè)緩存即是cache。src/runtime/mcache.go:mcache定義了cache的數(shù)據(jù)結(jié)構(gòu)

alloc為mspan的指針數(shù)組,數(shù)組大小為class總數(shù)的2倍。數(shù)組中每個(gè)元素代表了一種class類型的span列表,每種class類型都有兩組span列表,第一組列表中所表示的對(duì)象中包含了指針,第二組列表中所表示的對(duì)象不含有指針,這么做是為了提高GC掃描性能,對(duì)于不包含指針的span列表,沒必要去掃描。根據(jù)對(duì)象是否包含指針,將對(duì)象分為noscan和scan兩類,其中noscan代表沒有指針,而scan則代表有指針,需要GC進(jìn)行掃描。mcache和span的對(duì)應(yīng)關(guān)系如下圖所示:

mchache在初始化時(shí)是沒有任何span的,在使用過程中會(huì)動(dòng)態(tài)的從central中獲取并緩存下來,跟據(jù)使用情況,每種class的span個(gè)數(shù)也不相同。上圖所示,class 0的span數(shù)比class1的要多,說明本線程中分配的小對(duì)象要多一些。

cache作為線程的私有資源為單個(gè)線程服務(wù),而central則是全局資源,為多個(gè)線程服務(wù),當(dāng)某個(gè)線程內(nèi)存不足時(shí)會(huì)向central申請(qǐng),當(dāng)某個(gè)線程釋放內(nèi)存時(shí)又會(huì)回收進(jìn)central。src/runtime/mcentral.go:mcentral定義了central數(shù)據(jù)結(jié)構(gòu):

lock: 線程間互斥鎖,防止多線程讀寫沖突

spanclass : 每個(gè)mcentral管理著一組有相同class的span列表

nonempty: 指還有內(nèi)存可用的span列表

empty: 指沒有內(nèi)存可用的span列表

nmalloc: 指累計(jì)分配的對(duì)象個(gè)數(shù)線程從central獲取span步驟如下:

將span歸還步驟如下:

從mcentral數(shù)據(jù)結(jié)構(gòu)可見,每個(gè)mcentral對(duì)象只管理特定的class規(guī)格的span。事實(shí)上每種class都會(huì)對(duì)應(yīng)一個(gè)mcentral,這個(gè)mcentral的集合存放于mheap數(shù)據(jù)結(jié)構(gòu)中。src/runtime/mheap.go:mheap定義了heap的數(shù)據(jù)結(jié)構(gòu):

lock: 互斥鎖

spans: 指向spans區(qū)域,用于映射span和page的關(guān)系

bitmap:bitmap的起始地址

arena_start: arena區(qū)域首地址

arena_used: 當(dāng)前arena已使用區(qū)域的最大地址

central: 每種class對(duì)應(yīng)的兩個(gè)mcentral

從數(shù)據(jù)結(jié)構(gòu)可見,mheap管理著全部的內(nèi)存,事實(shí)上Golang就是通過一個(gè)mheap類型的全局變量進(jìn)行內(nèi)存管理的。mheap內(nèi)存管理示意圖如下:

系統(tǒng)預(yù)分配的內(nèi)存分為spans、bitmap、arean三個(gè)區(qū)域,通過mheap管理起來。接下來看內(nèi)存分配過程。

針對(duì)待分配對(duì)象的大小不同有不同的分配邏輯:

(0, 16B) 且不包含指針的對(duì)象: Tiny分配

(0, 16B) 包含指針的對(duì)象:正常分配

[16B, 32KB] : 正常分配

(32KB, -) : 大對(duì)象分配其中Tiny分配和大對(duì)象分配都屬于內(nèi)存管理的優(yōu)化范疇,這里暫時(shí)僅關(guān)注一般的分配方法。

以申請(qǐng)size為n的內(nèi)存為例,分配步驟如下:

Golang內(nèi)存分配是個(gè)相當(dāng)復(fù)雜的過程,其中還摻雜了GC的處理,這里僅僅對(duì)其關(guān)鍵數(shù)據(jù)結(jié)構(gòu)進(jìn)行了說明,了解其原理而又不至于深陷實(shí)現(xiàn)細(xì)節(jié)。1、Golang程序啟動(dòng)時(shí)申請(qǐng)一大塊內(nèi)存并劃分成spans、bitmap、arena區(qū)域

2、arena區(qū)域按頁劃分成一個(gè)個(gè)小塊。

3、span管理一個(gè)或多個(gè)頁。

4、mcentral管理多個(gè)span供線程申請(qǐng)使用

5、mcache作為線程私有資源,資源來源于mcentral。


網(wǎng)頁題目:go語言程序所占用內(nèi)存 go 限制內(nèi)存
文章URL:http://weahome.cn/article/hgjhse.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部