激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

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

服務器之家 - 腳本之家 - Golang - 深入理解golang:內存分配原理

深入理解golang:內存分配原理

2020-11-04 23:48九卷 Golang

在說明golang內存分配之前,先了解下Linux系統內存相關的基礎知識,有助于理解golang內存分配原理。

一、Linux系統內存

在說明golang內存分配之前,先了解下Linux系統內存相關的基礎知識,有助于理解golang內存分配原理。

1.1 虛擬內存技術

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

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

就是把程序分為若干個部分,稱為覆蓋塊(overlay),核心思想就是分解(跟現代架構技術中分解、分模塊思想很相近)。然后只把那些需要用到的指令和數據保存在內存中,而把其余的指令和數據保存在內存外。關鍵是需要程序員手動來分塊。

這種技術有什么問題呢?

這種技術必須由程序員手工把一個大的程序劃分為若干個小的功能模塊,并確定各個模塊之間的調用關系。手工做這種事情很費時費力,使得編程復雜度增加。但是,程序員總是愛“偷懶”的,于是,人們去尋找更好的方案。

這個方案就是虛擬內存技術,它的基本思路:

  • 程序運行進程的總大小可以超過實際可用的物理內存的大小。每個進程都可以有自己獨立的虛擬地址空間。然后通過CPU和MMU把虛擬內存地址轉換為實際物理地址。

這個就相當于在物理內存和程序之間增加了一個中間層,虛擬內存。

虛擬存儲也可以看作是對內存的一種抽象。而且這種抽象帶來諸多好處:

  • 它將內存看成是一個存儲在磁盤上的地址空間的高速緩存,在內存中只保留了活動區域,可以根據需要在磁盤和內存間來回傳送數據,高效使用內存。
  • 它為每個進程提供了一致的地址空間,簡化了存儲的管理。

對進程起到保護作用,不被其他進程地址空間破壞,因為每個進程的地址空間都是相互獨立。

  • (程序:靜態的程序;進程:動態的,可以看作是程序的一個實例)
  • 壞處:就是復雜度進一步增加,這也是必然的。不過相比帶來的好處,復雜度的增加還是可以接受,并克服。

Linux中對進程的處理抽象成了一個結構體 task_struct ,我前面文章有對這個結構體的介紹。下面就看看進程的內存。

1.2 進程的內存

進程內存在linux(32位)中的布局:

深入理解golang:內存分配原理

來自: https://manybutfinite.com/post/anatomy-of-a-program-in-memory/

最高位的1GB是linux內核空間,用戶代碼不能寫,否則觸發段錯誤。下面的3GB是進程使用的內存。

  • Kernel space:linux內核空間內存
  • Stack:進程??臻g,程序運行時使用。它向下增長,系統自動管理
  • Memory Mapping Segment:內存映射區,通過mmap系統調用,將文件映射到進程的地址空間,或者匿名映射。
  • Heap:堆空間。這個就是程序里動態分配的空間。linux下使用malloc調用擴展(用brk/sbrk擴展內存空間),free函數釋放(也就是縮減內存空間)
  • BSS段:包含未初始化的靜態變量和全局變量
  • Data段:代碼里已初始化的靜態變量、全局變量
  • Text段:代碼段,進程的可執行文件

二、內存管理中的一些常見問題

  1. 未能釋放已經不再使用的內存 - 內存泄漏
  2. 指向不可用的內存指針 - 野指針
  3. 指針所指向的對象已經被回收了,但是指向該對象的指針仍舊指向已經回收的內存地址 - 懸掛指針
  4. 分配或釋放內存太快或者太慢
  5. 分配內存大小不合理,造成內存碎片問題
  6. 內存碎片問題

三、TCMalloc

可以查看前面的文章TCMalloc內存分配簡析,TCMalloc內存分配器的原理和golang內存分配器原理相近,所以理解了TCMalloc,golang內存分配原理也就理解大半,不過golang對它也有一些改動。

四、golang內存

4.1 golang怎么解決常見內存問題

golang是怎么解決 二 的內存管理中的常見問題的呢?

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

針對下面的4、5、6 這三種問題,golang采用了多級緩存,預分配的方法,來加快內存分配和釋放回收,盡量減少內存碎片。詳見TCMalloc內存分配簡析 。

4.2 為什么要重新寫一個內存分配器

內核已經有一個malloc的內存分配器,為什么還有重寫一個內存分配器?

可以看到,malloc是一個很悠久的內存分配器,但是隨著時代的發展,多核多線程已經普及,為了更好的應用多線程,提高程序效率,以及改進內存碎片,所以重新寫了一個內存分配器。從這里TCMalloc內存分配簡析 可以看出TCMaloc的優點,它將內存劃分為多級別,減少鎖的開銷。而且每個線程的緩存又分開了多個小的對象,以減少內存碎片。等等優化改進。

所以go內存分配也繼承了這些優點。go還有一個原因,那就是go還有GC,需要配合內存的垃圾回收。

4.3 內存管理到底管理哪個區域

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

4.4 golang內存中的概念

golang內存分配的基本思想來自TCMalloc,所以go內存分配中的幾個概念與TCMalloc很相似,可以看看TCMalloc 中的概念 。

mspan

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

就連名字也很像,mspan中的m應該是memory的第一個字母。

mcache

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

mcentral

mcentral跟tcmalloc中的CentralCache相似,當mcache中空間不夠用,可以向mcentral申請內存??梢岳斫鉃閙central為mcache的一個“緩存庫”,供mcaceh使用。它的內存組成單位也是mspan。

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

mheap

mheap跟tcmalloc中的PageHeap相似,負責大內存的分配。當mcentral內存不夠時,可以向mheap申請。那mheap沒有內存資源呢?跟tcmalloc一樣,向OS操作系統申請。

還有,大于32KB的內存,也是直接向mheap申請。

總結

golang內存分配幾個相關概念,用圖來總結一下:

深入理解golang:內存分配原理

后面再進一步分析golang的內存分配原理。

五、參考

  • 可視化golang內存管理
  • 《操作系統的設計與實現》
  • a-program-in-memory linux內核分析很棒的文章

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

延伸 · 閱讀

精彩推薦
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

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

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

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

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

    golang 通過ssh代理連接mysql的操作

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

    a165861639710342021-03-08
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

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

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
主站蜘蛛池模板: 精品国产一区二区三区天美传媒 | 黄网站免费观看视频 | 性爱视频免费 | 成人三级电影网 | 国产成人高清成人av片在线看 | 久久亚洲美女视频 | 亚洲精品午夜视频 | 视频一区二区国产 | 4399一级成人毛片 | 久久久久97国产精 | 国产成人高潮免费观看精品 | free台湾极品性hd | 91网视频 | 深夜毛片免费看 | 美女久久久久久久久 | 日本在线播放一区二区 | 久久成年网站 | 九九热在线视频观看这里只有精品 | 中文字幕 亚洲一区 | 午夜影院操 | 色妹子久久 | 91网址在线观看 | 一区二区精品在线 | 国产高清美女一级毛片久久 | 一级毛片在线免费观看 | 娇妻被各种姿势c到高潮小说 | 国产成年人在线观看 | 日本s级毛片免费观看 | sese在线视频| 黄网站免费在线看 | 国内精品国产三级国产a久久 | 国产精品免费观看视频 | 能直接看av的网站 | 黄色大片网站在线观看 | 99亚洲| 国产在线看一区 | 奇米影视亚洲精品一区 | 一本视频在线观看 | 久久久99精品视频 | av在线播放免费 | 极品销魂一区二区三区 |