go語言內(nèi)存泄露,go 閉包 內(nèi)存泄露

go語言的出現(xiàn)非常奇怪,有幾個(gè)問題請高手答案一下~~~~??

1:go與c語言相比,go有垃圾回收,不會(huì)造成內(nèi)存泄露問題,go的語法簡潔優(yōu)美,同樣的c++100行代碼go大概50行可以做到,go的目標(biāo)是能做C++能做的事,雖然目前可能不太實(shí)際

創(chuàng)新互聯(lián)是專業(yè)的欒城網(wǎng)站建設(shè)公司,欒城接單;提供網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行欒城網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

2:go的并行機(jī)制并不是一般的線程,通過channel和goroutine來實(shí)現(xiàn),比線程還要輕量級(jí)很多,所以go適合高并發(fā)的服務(wù)器端

3:go是系統(tǒng)級(jí)別的語言,相當(dāng)于c語言,java c#都是算比較高級(jí)的語言,這個(gè)不太好比,效率的話目前確實(shí)是要高一些,而且不需要外部依賴,所以go還是很強(qiáng)大的

一個(gè)程序會(huì)產(chǎn)生哪幾個(gè)文件夾?

一個(gè)程序產(chǎn)生的文件夾如下:

一、程序的組成部分

Linux下程序大都是由以下幾部分組成:

二進(jìn)制文件:也就是可以運(yùn)行的程序文件

庫文件:就是通常我們見到的lib目錄下的文件

配置文件:

幫助文檔:通常是我們在Linux下用man命令查看的命令的文檔

二、Linux下程序的存放目錄

Linux程序的存放目錄大致有三個(gè)地方:

/etc, /bin, /sbin, /lib :系統(tǒng)啟動(dòng)就需要用到的程序,這些目錄不能掛載額外的分區(qū),必須在根文件系統(tǒng)的分區(qū)上

/usr/bin,/usr/sbin,/usr/lib:操作系統(tǒng)核心功能,可以單獨(dú)分區(qū)

/usr/local/bin,/usr/local/sbin:/usr/local/lib:/usr/local/etc:/usr/local/man:這幾個(gè)目錄用于安裝第三方程序,分別對應(yīng)了二進(jìn)制文件、庫文件、配置文件、幫助文檔的目錄

通常來說源碼安裝程序時(shí),就安裝在 /usr/local目錄下

原文地址:

推薦文章

ubuntu16.04環(huán)境下fatal error: lua.h: No such file or directory

DB2數(shù)據(jù)庫建表報(bào)錯(cuò)

MySQL、Oracle與DB2數(shù)據(jù)庫差異

jQueryrocket

jQueryrocket

js文件替換

PHP源文件編碼與變量編碼的判斷

PHP判斷字符串所屬編碼:ASCII、GB2312、GBK、UTF-8、ISO-8859-1

PHP的URL編碼解碼與原理、自定義實(shí)現(xiàn)

Odoo13_前端圖標(biāo)按鈕實(shí)例

Odoo13_向?qū)?yīng)用之軟刪除

macOS一條命令查看當(dāng)前wifi密碼

編譯redis-5.0.8報(bào)錯(cuò)/usr/bin/ld: cannot find -latomic解決方法

頻繁調(diào)用ConcurrentLinkedQueue類的offer和remove方法會(huì)內(nèi)存泄露

記一次排查問題用到工具

【jvisualvm】堆查器使用的內(nèi)存不足

開發(fā)規(guī)范

各種http報(bào)錯(cuò)的報(bào)錯(cuò)的狀態(tài)碼的分析

Springboot整合Elasticsearch

Wang ?? Free Fast Stable Best Just try it_v2....

md5

表空間

create_index

非額度合同和額度合同

如何在linux中查找python安裝包的路徑

Golang中的SingleFlight與CyclicBarrier

linux安裝protoc

protobuf 的優(yōu)缺點(diǎn)

Xshell 連接 VirtualBox

限制 input 輸入框只能輸入純數(shù)字

【golang】海量數(shù)據(jù)去重-布隆過濾器

在做域名爆破中,遇到了把一個(gè)300G的子域名json文件進(jìn)行去重,一開始是考慮使用字典進(jìn)行去重,但是數(shù)據(jù)量大了,會(huì)造成內(nèi)存泄露。看網(wǎng)上資料介紹了一種方案,就是使用布隆過濾器。

布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu),概率型數(shù)據(jù)結(jié)構(gòu),特定是高效插入和查詢,可以用來告訴你“某一值一定不存在或者kennel存在”。

相比于傳統(tǒng)的map、set等數(shù)據(jù)結(jié)構(gòu),占用空間更少,但其返回結(jié)果是概率型的,不確定。

布隆過濾器內(nèi)部維護(hù)一個(gè)bitArray(位數(shù)組),開始所有數(shù)據(jù)為0,當(dāng)一個(gè)元素過來時(shí),能過多個(gè)哈希函數(shù)(hash1、hash2、hash3)計(jì)算不同的hash值,并通過hash值找到bitArray的下標(biāo),將里面的值改為由0變?yōu)?。布隆過濾器有一個(gè)誤判率,誤判率越低,數(shù)組越長,所在空間越大,誤判率越高,數(shù)組越小,所占空間越小。

這里貼上一個(gè)技術(shù)大牛的博客地址,里面對布隆過濾器用法以及在redis里面處理緩存穿透問題的詳細(xì)介紹。

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

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

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

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

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

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

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

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

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

邏輯的復(fù)雜度不言而喻,從上面的匯編中可看到, heap() 函數(shù)調(diào)用了 runtime.newobject() 方法,它會(huì)調(diào)用 mallocgc 方法從 mcache 上申請內(nèi)存,申請的內(nèi)部邏輯前面文章已經(jīng)講述過。堆內(nèi)存分配不僅分配上邏輯比棧空間分配復(fù)雜,它最致命的是會(huì)帶來很大的管理成本,Go 語言要消耗很多的計(jì)算資源對其進(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ì)被外部使用,則使用棧空間,否則就要使用堆空間。

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

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

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

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

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

這里的多級(jí)間接指的是,對某個(gè)引用類對象中的引用類成員進(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ù)變量。有興趣的可以自己測試一下。

只要使用了 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)目中還是怎么方便怎么寫,功能完成后通過性能分析找到瓶頸所在,再對局部進(jìn)行優(yōu)化。

本文標(biāo)題:go語言內(nèi)存泄露,go 閉包 內(nèi)存泄露
文章源于:http://m.kartarina.com/article42/heijec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)搜索引擎優(yōu)化網(wǎng)站設(shè)計(jì)公司定制開發(fā)云服務(wù)器微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
主站蜘蛛池模板: 成人免费无码大片A毛片抽搐 | 亚洲AV蜜桃永久无码精品| 久久无码人妻一区二区三区| 无码任你躁久久久久久老妇App | 精品无码人妻一区二区三区18| 丰满日韩放荡少妇无码视频| 西西大胆无码视频免费| 国精品无码A区一区二区| 亚洲av无码兔费综合| 亚洲AV无码不卡在线播放| 惠民福利中文字幕人妻无码乱精品| 久久精品无码专区免费东京热| 亚洲午夜无码AV毛片久久| 永久免费av无码不卡在线观看 | 午夜人性色福利无码视频在线观看| 无码人妻丰满熟妇区五十路| 国产成人精品无码播放| 久久国产精品无码网站| 丰满爆乳无码一区二区三区| 中文字幕AV无码一区二区三区| 伊人久久综合无码成人网| 久久中文精品无码中文字幕| 在线看片无码永久免费aⅴ| 亚洲一区二区三区无码国产| 亚洲av无码成h人动漫无遮挡| 在线观看免费无码专区| 国内精品人妻无码久久久影院导航| 亚洲国产精品成人AV无码久久综合影院 | 亚洲自偷自偷偷色无码中文 | 青青爽无码视频在线观看| 久久久久久AV无码免费网站| 国产亚洲大尺度无码无码专线| 波多野42部无码喷潮在线| 国产AV无码专区亚洲AV蜜芽| 无码AV大香线蕉| 无码专区国产精品视频| 免费无码一区二区| 东京热无码一区二区三区av| 成在人线av无码免费高潮水| 一夲道无码人妻精品一区二区| 国产精品成人无码久久久久久|