xiaohanliang
Golang
Golang
  • review
  • DATA STRUCT
    • Slice
    • Map
    • Lock
    • Chanel
    • Pool
    • Interface
  • SCHEDULE
    • 为什么要设计Go协程
    • GMP都是干什么的
    • 一次完整的调度
    • 什么是G栈
    • P&M剥离
    • 常见的暂停操作
  • OTHERS
    • GC介绍
    • 内存介绍
    • 内存分析
Powered by GitBook
On this page
  • Introduction
  • 分配的过程

Was this helpful?

  1. OTHERS

内存介绍

PreviousGC介绍Next内存分析

Last updated 4 years ago

Was this helpful?

Introduction

内存里的很多页组合在一起构成span, 但是名为span的结构我们并不会拿来使用, 我们会把这些大页按照8的倍数切一切, 分成很多个规格, 然后把这些切好的东西, 按照规格存起来备用

每个M手持一组切好的内存, 这一组里面按照规格五花八门大的小的都有, 如果G需要直接从里面取就好, 每个M人人都有, 如果消耗光了, M就会去central哪里补充一些进来

分配的过程

分配的过程我们要从new(data)开始讲起, 我们刚刚说的内存都是堆内存, 为了能复现堆内存分配(而不是栈内存) 我们要使用"-gcflags -l"开始关闭内联, 同时将分配到的指针用作函数返回值.

一切就绪, new(data)会被翻译成runtime.newobject(typ), 根据这个对象的大小, 我们开始找规格, 比如大小为17的数据类型, 我们只能使用大小为24(8的倍数)的规格来承载, 大部分情况下, 整体的流程是:

  • 检查自己家有没有: mcache[class].freelist看看有没有24规格的给你用

  • 如果自己家没有就要去central补充一下这个规格的object, 也就是往mcache[class]里补充mspan

  • 如果central也没有这种规格的, 那么我们要去heap里补充, heap里有一大堆没切过的大span, 这些span拿来要切成24的规格, 然后往central里补充

比较有意思的是大小小于16的是tiny_size, 这种不会一人占一个object, 这种我们会尝试好几个人挤一个object, 并通过tinyoffset维护当前存到哪儿了

而大于32K的单位就不走以上规则, 这种超大对象会直接从heap里申请span