3-数据类型内存结构-map

4. map

map变量只有8个字节,指向map对象自己。

var var_map map[int64]int64 = map[int64]int64{0x1234:0x1234};
1878 "".var_map SBSS size=8
var var2_map map[int64]int64 = map[int64]int64{0x1234:0x1234};

1、调用运行时runtime.makemap_small()创建一个hmap结构体。

// makehmap_small implements Go map creation for make(map[k]v) and
// make(map[k]v, hint) when hint is known to be at most bucketCnt
// at compile time and the map needs to be allocated on the heap.
func makemap_small() *hmap {
    h := new(hmap)
    h.hash0 = fastrand()
    return h
}

// A header for a Go map.
type hmap struct {
    // Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.
    // Make sure this stays in sync with the compiler's definition.
    count     int // # live cells == size of map.  Must be first (used by len() builtin)
    flags     uint8
    B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
    noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
    hash0     uint32 // hash seed

    buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
    oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
    nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

    extra *mapextra // optional fields
}

2、mapassign_fast64获取key对应值位置

func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
src\runtime\type.go
type _type struct {
    size       uintptr  //8 字节
    ptrdata    uintptr  //8 字节 size of memory prefix holding all pointers
    hash       uint32   //4 字节
    tflag      tflag    //1 字节
    align      uint8    //1 字节  0x08 8字节对象
    fieldalign uint8    //1 字节  0x08 8字节对象 
    kind       uint8    //1 字节   0x14=20=RUNTIME_TYPE_KIND_INTERFACE
    alg        *typeAlg //8 字节
    // gcdata stores the GC type data for the garbage collector.
    // If the KindGCProg bit is set in kind, gcdata is a GC program.
    // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
    gcdata    *byte     //8
    str       nameOff   //4
    ptrToThis typeOff   //4
}

type maptype struct {  //80字节
    typ        _type    //48字节
    key        *_type   //8字节
    elem       *_type   //8字节
    bucket     *_type // 8字节 internal type representing a hash bucket
    keysize    uint8  // 1字节 size of key slot
    valuesize  uint8  // 1字节 size of value slot
    bucketsize uint16 // 2字节 size of bucket
    flags      uint32 // 4字节
}

map底层类型信息 maptype 可以看出有80个字节
type.map[int64]int64 SRODATA dupok size=80

   2247 type..namedata.*map[int64]int64- SRODATA dupok size=19
   2248         0x0000 00 00 10 2a 6d 61 70 5b 69 6e 74 36 34 5d 69 6e  ...*map[int64]in
   2249         0x0010 74 36 34                                         t64
   2250 type.*map[int64]int64 SRODATA dupok size=56
   2251         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
   2252         0x0010 d1 14 ff d7 00 08 08 36 00 00 00 00 00 00 00 00  .......6........
   2253         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2254         0x0030 00 00 00 00 00 00 00 00                          ........
   2255         rel 24+8 t=1 runtime.algarray+80
   2256         rel 32+8 t=1 runtime.gcbits.01+0
   2257         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
   2258         rel 48+8 t=1 type.map[int64]int64+0
   2259 type.map[int64]int64 SRODATA dupok size=80
   2260         0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
   2261         0x0010 9c 10 d3 02 02 08 08 35 00 00 00 00 00 00 00 00  .......5........
   2262         0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2263         0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
   2264         0x0040 00 00 00 00 00 00 00 00 08 08 90 00 04 00 00 00  ................
   2265         rel 24+8 t=1 runtime.algarray+0
   2266         rel 32+8 t=1 runtime.gcbits.01+0
   2267         rel 40+4 t=5 type..namedata.*map[int64]int64-+0
   2268         rel 44+4 t=6 type.*map[int64]int64+0
   2269         rel 48+8 t=1 type.int64+0
   2270         rel 56+8 t=1 type.int64+0
   2271         rel 64+8 t=1 type.noalg.map.bucket[int64]int64+0

3、赋值

     39         0x0040 00064 (type.go:41)       CALL    runtime.makemap_small(SB)   //创建hmap对象
     40         0x0045 00069 (type.go:41)       PCDATA  $2, $1
     41         0x0045 00069 (type.go:41)       MOVQ    (SP), AX    //将hmap对象地址赋值给AX
     42         0x0049 00073 (type.go:41)       PCDATA  $2, $0
     43         0x0049 00073 (type.go:41)       PCDATA  $0, $1
     44         0x0049 00073 (type.go:41)       MOVQ    AX, "".var2_map+136(SP) //将hmap对象地址赋值给var2_map
     45         0x0051 00081 (type.go:41)       MOVQ    $4660, ""..autotmp_27+104(SP)   //临时变量赋值为0x1234
     46         0x005a 00090 (type.go:41)       MOVQ    $4660, ""..autotmp_28+96(SP)    //临时变量赋值为0x1234
     47         0x0063 00099 (type.go:41)       PCDATA  $2, $1
     48         0x0063 00099 (type.go:41)       LEAQ    type.map[int64]int64(SB), AX    //将map[int64]int64类型地址赋值给AX
     49         0x006a 00106 (type.go:41)       PCDATA  $2, $0
     50         0x006a 00106 (type.go:41)       MOVQ    AX, (SP)    //将map类型信息压入栈
     51         0x006e 00110 (type.go:41)       PCDATA  $2, $1
     52         0x006e 00110 (type.go:41)       MOVQ    "".var2_map+136(SP), AX 
     53         0x0076 00118 (type.go:41)       PCDATA  $2, $0
     54         0x0076 00118 (type.go:41)       MOVQ    AX, 8(SP)   //将map变量地址压入栈
     55         0x007b 00123 (type.go:41)       MOVQ    ""..autotmp_27+104(SP), AX
     56         0x0080 00128 (type.go:41)       MOVQ    AX, 16(SP)  //将临时变量压入栈
     57         0x0085 00133 (type.go:41)       CALL    runtime.mapassign_fast64(SB) //获取key对应的值地址
     58         0x008a 00138 (type.go:41)       PCDATA  $2, $1
     59         0x008a 00138 (type.go:41)       MOVQ    24(SP), AX
     60         0x008f 00143 (type.go:41)       MOVQ    AX, ""..autotmp_29+184(SP)  //返回值赋值给临时变量
     61         0x0097 00151 (type.go:41)       TESTB   AL, (AX)
     62         0x0099 00153 (type.go:41)       MOVQ    ""..autotmp_28+96(SP), CX   //将0x1234放到寄存器CX
     63         0x009e 00158 (type.go:41)       PCDATA  $2, $0
     64         0x009e 00158 (type.go:41)       MOVQ    CX, (AX)    //将值0x1234赋值给key对应的val指向地址
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • map 的底层如何实现 首先声明我用的 Go 版本:go version go1.9.2 darwin/amd64...
    CCCCCCMake阅读 793评论 0 1
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,084评论 1 32
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,446评论 0 13
  • 几乎每天早上醒来的第一件事就是搜索你的消息。我也不知道什么时候才到头。
    往前走啊不回头阅读 275评论 0 0
  • 给我们讲保险的老师,是一个中等身材的女老师。也负责考研指导。她讲话很快,一节课都在讲,几乎不停顿。但是讲的很简单。...
    温柔的小仙女阅读 361评论 0 0