国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Golang - 深入理解golang:內(nèi)存分配原理

深入理解golang:內(nèi)存分配原理

2020-11-04 23:48九卷 Golang

在說(shuō)明golang內(nèi)存分配之前,先了解下Linux系統(tǒng)內(nèi)存相關(guān)的基礎(chǔ)知識(shí),有助于理解golang內(nèi)存分配原理。

一、Linux系統(tǒng)內(nèi)存

在說(shuō)明golang內(nèi)存分配之前,先了解下Linux系統(tǒng)內(nèi)存相關(guān)的基礎(chǔ)知識(shí),有助于理解golang內(nèi)存分配原理。

1.1 虛擬內(nèi)存技術(shù)

在早期內(nèi)存管理中,如果程序太大,超過(guò)了空閑內(nèi)存容量,就沒(méi)有辦法把全部程序裝入到內(nèi)存,這時(shí)怎么辦? 在許多年前,人們采用了一種叫做覆蓋技術(shù),這樣一種解決方案。

這是一種什么樣的解決方案?

就是把程序分為若干個(gè)部分,稱為覆蓋塊(overlay),核心思想就是分解(跟現(xiàn)代架構(gòu)技術(shù)中分解、分模塊思想很相近)。然后只把那些需要用到的指令和數(shù)據(jù)保存在內(nèi)存中,而把其余的指令和數(shù)據(jù)保存在內(nèi)存外。關(guān)鍵是需要程序員手動(dòng)來(lái)分塊。

這種技術(shù)有什么問(wèn)題呢?

這種技術(shù)必須由程序員手工把一個(gè)大的程序劃分為若干個(gè)小的功能模塊,并確定各個(gè)模塊之間的調(diào)用關(guān)系。手工做這種事情很費(fèi)時(shí)費(fèi)力,使得編程復(fù)雜度增加。但是,程序員總是愛(ài)“偷懶”的,于是,人們?nèi)ふ腋玫姆桨浮?/p>

這個(gè)方案就是虛擬內(nèi)存技術(shù),它的基本思路:

  • 程序運(yùn)行進(jìn)程的總大小可以超過(guò)實(shí)際可用的物理內(nèi)存的大小。每個(gè)進(jìn)程都可以有自己獨(dú)立的虛擬地址空間。然后通過(guò)CPU和MMU把虛擬內(nèi)存地址轉(zhuǎn)換為實(shí)際物理地址。

這個(gè)就相當(dāng)于在物理內(nèi)存和程序之間增加了一個(gè)中間層,虛擬內(nèi)存。

虛擬存儲(chǔ)也可以看作是對(duì)內(nèi)存的一種抽象。而且這種抽象帶來(lái)諸多好處:

  • 它將內(nèi)存看成是一個(gè)存儲(chǔ)在磁盤上的地址空間的高速緩存,在內(nèi)存中只保留了活動(dòng)區(qū)域,可以根據(jù)需要在磁盤和內(nèi)存間來(lái)回傳送數(shù)據(jù),高效使用內(nèi)存。
  • 它為每個(gè)進(jìn)程提供了一致的地址空間,簡(jiǎn)化了存儲(chǔ)的管理。

對(duì)進(jìn)程起到保護(hù)作用,不被其他進(jìn)程地址空間破壞,因?yàn)槊總€(gè)進(jìn)程的地址空間都是相互獨(dú)立。

  • (程序:靜態(tài)的程序;進(jìn)程:動(dòng)態(tài)的,可以看作是程序的一個(gè)實(shí)例)
  • 壞處:就是復(fù)雜度進(jìn)一步增加,這也是必然的。不過(guò)相比帶來(lái)的好處,復(fù)雜度的增加還是可以接受,并克服。

Linux中對(duì)進(jìn)程的處理抽象成了一個(gè)結(jié)構(gòu)體 task_struct ,我前面文章有對(duì)這個(gè)結(jié)構(gòu)體的介紹。下面就看看進(jìn)程的內(nèi)存。

1.2 進(jìn)程的內(nèi)存

進(jìn)程內(nèi)存在linux(32位)中的布局:

深入理解golang:內(nèi)存分配原理

來(lái)自: https://manybutfinite.com/post/anatomy-of-a-program-in-memory/

最高位的1GB是linux內(nèi)核空間,用戶代碼不能寫,否則觸發(fā)段錯(cuò)誤。下面的3GB是進(jìn)程使用的內(nèi)存。

  • Kernel space:linux內(nèi)核空間內(nèi)存
  • Stack:進(jìn)程棧空間,程序運(yùn)行時(shí)使用。它向下增長(zhǎng),系統(tǒng)自動(dòng)管理
  • Memory Mapping Segment:內(nèi)存映射區(qū),通過(guò)mmap系統(tǒng)調(diào)用,將文件映射到進(jìn)程的地址空間,或者匿名映射。
  • Heap:堆空間。這個(gè)就是程序里動(dòng)態(tài)分配的空間。linux下使用malloc調(diào)用擴(kuò)展(用brk/sbrk擴(kuò)展內(nèi)存空間),free函數(shù)釋放(也就是縮減內(nèi)存空間)
  • BSS段:包含未初始化的靜態(tài)變量和全局變量
  • Data段:代碼里已初始化的靜態(tài)變量、全局變量
  • Text段:代碼段,進(jìn)程的可執(zhí)行文件

二、內(nèi)存管理中的一些常見(jiàn)問(wèn)題

  1. 未能釋放已經(jīng)不再使用的內(nèi)存 - 內(nèi)存泄漏
  2. 指向不可用的內(nèi)存指針 - 野指針
  3. 指針?biāo)赶虻膶?duì)象已經(jīng)被回收了,但是指向該對(duì)象的指針仍舊指向已經(jīng)回收的內(nèi)存地址 - 懸掛指針
  4. 分配或釋放內(nèi)存太快或者太慢
  5. 分配內(nèi)存大小不合理,造成內(nèi)存碎片問(wèn)題
  6. 內(nèi)存碎片問(wèn)題

三、TCMalloc

可以查看前面的文章TCMalloc內(nèi)存分配簡(jiǎn)析,TCMalloc內(nèi)存分配器的原理和golang內(nèi)存分配器原理相近,所以理解了TCMalloc,golang內(nèi)存分配原理也就理解大半,不過(guò)golang對(duì)它也有一些改動(dòng)。

四、golang內(nèi)存

4.1 golang怎么解決常見(jiàn)內(nèi)存問(wèn)題

golang是怎么解決 二 的內(nèi)存管理中的常見(jiàn)問(wèn)題的呢?

針對(duì)上面的1、2、3 這三種問(wèn)題,golang使用自動(dòng)垃圾回收機(jī)制,一般情況下,都不使用指針運(yùn)算(要運(yùn)算用unsafe包),很少的指針使用。當(dāng)然,內(nèi)存泄漏問(wèn)題不能完全根除,但是可以解決一大部分問(wèn)題。

針對(duì)下面的4、5、6 這三種問(wèn)題,golang采用了多級(jí)緩存,預(yù)分配的方法,來(lái)加快內(nèi)存分配和釋放回收,盡量減少內(nèi)存碎片。詳見(jiàn)TCMalloc內(nèi)存分配簡(jiǎn)析 。

4.2 為什么要重新寫一個(gè)內(nèi)存分配器

內(nèi)核已經(jīng)有一個(gè)malloc的內(nèi)存分配器,為什么還有重寫一個(gè)內(nèi)存分配器?

可以看到,malloc是一個(gè)很悠久的內(nèi)存分配器,但是隨著時(shí)代的發(fā)展,多核多線程已經(jīng)普及,為了更好的應(yīng)用多線程,提高程序效率,以及改進(jìn)內(nèi)存碎片,所以重新寫了一個(gè)內(nèi)存分配器。從這里TCMalloc內(nèi)存分配簡(jiǎn)析 可以看出TCMaloc的優(yōu)點(diǎn),它將內(nèi)存劃分為多級(jí)別,減少鎖的開銷。而且每個(gè)線程的緩存又分開了多個(gè)小的對(duì)象,以減少內(nèi)存碎片。等等優(yōu)化改進(jìn)。

所以go內(nèi)存分配也繼承了這些優(yōu)點(diǎn)。go還有一個(gè)原因,那就是go還有GC,需要配合內(nèi)存的垃圾回收。

4.3 內(nèi)存管理到底管理哪個(gè)區(qū)域

從上面的進(jìn)程內(nèi)存布局圖,可以看出一個(gè)進(jìn)程的內(nèi)存劃分了好多不同的區(qū)域,而內(nèi)存管理主要管理的就是Stack和Heap,其中Stack (棧)區(qū)主要由編譯器和系統(tǒng)管理,程序語(yǔ)言主要管理Heap(堆)。而且這里的進(jìn)程內(nèi)存指的是虛擬內(nèi)存。

4.4 golang內(nèi)存中的概念

golang內(nèi)存分配的基本思想來(lái)自TCMalloc,所以go內(nèi)存分配中的幾個(gè)概念與TCMalloc很相似,可以看看TCMalloc 中的概念 。

mspan

mspan跟tcmalloc中的span相似,它是golang內(nèi)存管理中的基本單位,也是由頁(yè)組成的,每個(gè)頁(yè)大小為8KB,與tcmalloc中span組成的默認(rèn)基本內(nèi)存單位頁(yè)大小相同。mspan里面按照8*2n大小(8b,16b,32b .... ),每一個(gè)mspan又分為多個(gè)object。

就連名字也很像,mspan中的m應(yīng)該是memory的第一個(gè)字母。

mcache

mcache跟tcmalloc中的ThreadCache相似,ThreadCache為每個(gè)線程的cache,同理,mcache可以為golang中每個(gè)Processor提供內(nèi)存cache使用,每一個(gè)mcache的組成單位也是mspan。

mcentral

mcentral跟tcmalloc中的CentralCache相似,當(dāng)mcache中空間不夠用,可以向mcentral申請(qǐng)內(nèi)存。可以理解為mcentral為mcache的一個(gè)“緩存庫(kù)”,供mcaceh使用。它的內(nèi)存組成單位也是mspan。

mcentral里有兩個(gè)雙向鏈表,一個(gè)鏈表表示還有空閑的mspan待分配,一個(gè)表示鏈表里的mspan都被分配了。

mheap

mheap跟tcmalloc中的PageHeap相似,負(fù)責(zé)大內(nèi)存的分配。當(dāng)mcentral內(nèi)存不夠時(shí),可以向mheap申請(qǐng)。那mheap沒(méi)有內(nèi)存資源呢?跟tcmalloc一樣,向OS操作系統(tǒng)申請(qǐng)。

還有,大于32KB的內(nèi)存,也是直接向mheap申請(qǐng)。

總結(jié)

golang內(nèi)存分配幾個(gè)相關(guān)概念,用圖來(lái)總結(jié)一下:

深入理解golang:內(nèi)存分配原理

后面再進(jìn)一步分析golang的內(nèi)存分配原理。

五、參考

  • 可視化golang內(nèi)存管理
  • 《操作系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)》
  • a-program-in-memory linux內(nèi)核分析很棒的文章

原文地址:https://www.cnblogs.com/jiujuan/p/13922551.html

延伸 · 閱讀

精彩推薦
  • Golanggo語(yǔ)言制作端口掃描器

    go語(yǔ)言制作端口掃描器

    本文給大家分享的是使用go語(yǔ)言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang 通過(guò)ssh代理連接mysql的操作

    golang 通過(guò)ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過(guò)ssh代理連接mysql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    a165861639710342021-03-08
  • GolangGolang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    天易獨(dú)尊11682021-06-09
  • Golanggolang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,...

    helight2992020-05-14
  • Golanggolang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說(shuō)起,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看...

    Go語(yǔ)言中文網(wǎng)11352020-05-21
  • GolangGolang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語(yǔ)言中標(biāo)識(shí)符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語(yǔ)言中標(biāo)識(shí)符允許由...

    4272021-11-24
  • Golanggo日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    go日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號(hào)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    SmallQinYan12302021-02-02
主站蜘蛛池模板: 国产精品久久久爽爽爽麻豆色哟哟 | 欧美日韩精品一区二区三区 | 国产一区二区视频在线 | 国产精品99久久久久久动医院 | 国产精品久久久99 | 午夜区| 国产成人精品一区二区 | 红杏首页 | 国产99一区二区 | 四虎视频 | 亚洲欧美在线观看 | 日韩精品在线一区 | 成人在线视频网站 | a吖2020天堂网 | 欧美精品在线一区二区三区 | 日韩电影一区二区在线观看 | 亚洲一区在线视频 | 亚洲免费视频观看 | 一区二区三区日韩 | av中文字幕在线观看 | 日韩小视频网站hq | 免费污网址 | 国产一区二区黑人欧美xxxx | 免费一区二区 | 国产第一区二区三区 | 亚洲国产精品一区二区三区 | 性欧美精品久久久久久久 | www.中文字幕.com | 美女爽到呻吟久久久久 | 精品乱子伦一区二区三区 | 一级毛片免费播放 | 大香伊蕉在人线视频777 | 一区二区在线视频 | 伊人伊人 | 亚洲精品免费看 | 日韩一区二区三区在线视频 | 大白屁股一区二区视频 | 激情欧美一区二区三区中文字幕 | 久久久久久综合 | a∨色狠狠一区二区三区 | 亚洲视频免费观看 |