AD

Golang 内存模型详解(一)

这篇文章主要介绍了Golang 内存模型详解(一),本文讲解了Go内存模型interface、,需要的朋友可以参考下

开始之前

首先,这是一篇菜B写的文章,可能会有理解错误的地方,发现错误请斧正,谢谢。

为了治疗我的懒癌早期,我一次就不写得太多了,这个系列想写很久了,每次都是开了个头就没有再写。这次争取把写完,弄成一个系列。

此 nil 不等彼 nil

先声明,这个标题有标题党的嫌疑。

Go 的类型系统是比较奇葩的,nil 的含义跟其它语言有些差别,这里举个例子(可以直接进入 **play.golang**/p/ezFhXX0dnB 运行查看结果):

package main

import "fmt"

type A struct {

}

func main() {

    var a *A = nil

    var ai interface{} = a

    var ei interface{} = nil

    fmt.Printf("ai == nil: %v\n", ai == nil)

    fmt.Printf("ai == ei: %v\n", ai == ei)

    fmt.Printf("ei == a: %v\n", a == ei)

    fmt.Printf("ei == nil: %v\n", ei == nil)

}

// -> 输出

// ai == nil: false

// ai == ei: false

// ei == a: false

// ei == nil: true

这里 ai != nil,对于没有用过 Go 的人来说比较费解,对我来说,这个算得上一门语言设计有歧义的地方(Golang FAQ 有对于此问题的描述,可以参考一下:**golang**/doc/faq#nil_error)。

简单的说就是 nil 代表 “zero value”(空值),对于不同类型,它具体所代表的值不同。比如上面的 a 为“*A 类型的空值”,而 ai 为“interface{} 类型的空值”。造成理解失误的最大问题在于,struct pointer 到 interface 有隐式转换(var ai interface{] = a,这里有个隐式转换),至于为什么对于 Go 这种在其它转换方面要求严格,而对于 interface 要除外呢,for convenience 吧,呵呵……

碰到了这个坑,我就开始好奇了,Go 的类型系统到底是什么样的?

Go 内存模型 - interface

概述

为了读懂下面的内容,你需要:

了解 C、Go 语言

Go 1.3 源代码 (**go.googlecode**/archive/go1.3.zip)

PS: 由于 Go 用到了 Plan9 C 这个小众的C编译器的扩展,比如在函数签名中使用 · 字符以区分 package/function(比如runtime·panic),这对理解不会产生什么影响。

PSS: 对于 Go runtime,可以参考src/pkg/reflect(reflect包)中的的代码,对类型系统的实现的理解有帮助。

Go 语言的类型定义可以在 src/pkg/runtime/ 目录下找到,主要由以下几个文件构成:

1.runtime.h
2.type.h

对于 interface 类型,主要看下面几个结构体定义:

1.InterfaceType
2.Itab
3.Iface
4.Eface

它们的C语言定义如下 (可以在 runtime.h 中找到):

InterfaceType:

代表了总的 interface 类型,其中:

1.Type: 类型描述,所有的类型都有这个类型描述(比如 array, map, slice)
2.mhdr 以及 m: interface 接口方法列表

复制代码 代码如下:

struct InterfaceType

{

    Type;

    Slice mhdr;

    IMethod m[];

};

Itab:

类似于虚函数表,该表不会被GC回收,其中:

1.inter: 指向具体的 interface 类型
2.type: 具体实现类型, 也即 receiver type
3.** 指向下一个函数表,因为 interface 可以 embed 多个 interface,因此实现为一个链表形式
4.bad: <略>
5.unsued: <略>
6.fun: 函数列表,每个元素是一个指向具体函数实现的指针

复制代码 代码如下:

struct  Itab

{

    InterfaceType*  inter;

    Type*   type;

    Itab*   link;

    int32   bad;

    int32   unused;

    void    (*fun[])(void);

};

Iface:

该类型为一般的 interface 类型所对应的数据结构,其中:

1.tab: 参见 Itab 的说明,尤其是 Itab::link
2.data: 指向具体数据(比如指向struct,当然,如果一个数据不超过一个字长,那么这个data就可以直接存放,不需要指针再做以及跳转)

复制代码 代码如下:

struct Iface

{

    Itab*   tab;

    void*   data;

};

Eface:

该类型为 interface{} (empty interface) 所对应的数据结构,其中:

1.type: 具体实现类型, 也即 receiver type
2.data: 同 Iface

复制代码 代码如下:

struct Eface

{

    Type*   type;

    void*   data;

};

他们的依赖关系如下图所示:

Golang 内存模型详解(一)

先到这里,下一篇将会举例子说明给一个 interface{} 类型的变量赋值后,其具体的内存结构是怎么样的。

打了几个小时,真费时间,争取这个系列不坑 (逃

标签: Golang, 内存模型
分类: Golang
时间: 2014-06-04

相关文章

  1. platform_device驱动模型详解

    linux platform_device驱动模型详解 platform在linux模型结构中,其实就是一种虚拟总线,没有对应的硬件结构. 其主要用来管理系统的外设资源,比如IO 内存 中断信号...... 这样内核就可 ...
  2. C++内存管理详解

    C++内存管理详解
  3. C/C++程序内存分配详解

    C/C++程序内存分配详解 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器 ...
  4. win socket 模型详解 (转)

    <转:http://www.cppblog.com/changshoumeng/articles/113441.html > Socket模型详解 两种Socket模式 一.选择模型 二.异步选择 三.事件选 ...
  5. JVM内存配置详解

    前段时间在一个项目的性能测试中又发生了一次OOM(Out of swap sapce),情形和以前网店版的那次差不多,比上次更奇怪的是,此次搞了几天之后啥都没调整系统就自动好了,死活没法再重现之前的OOM了!问题虽然蹊跷 ...
  6. [转]OSI七层模型详解

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于不同层的中继系统具有 ...
  7. 解析Android开发优化之:对Bitmap的内存优化详解

    在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常.所以,对于图片的内存优化,是An ...
  8. 理解Javascript_13_执行模型详解

    在<理解Javascript_12_执行模型浅析>一文中,我们初步的了解了执行上下文与作用域的概念,那么这一篇将深入分析执行上下文的构建过程,了解执行上下文.函数对象.作用域三者之间的关系. 函数执行环境 简 ...
  9. [转]Java虚拟机(JVM)中的内存设置详解

    在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步. PermGen space:全称是Permanent Generation space.就是说 ...
  10. CSS盒模型详解

    CSS盒模型,多么专业的一个术语.但你不要被它吓到,不过就是一些CSS基本属性的应用而已. CSS 盒模型 网页设计中的每个元素都是长方形的盒子.盒子的尺寸是怎样精确计算的,请看下图: 如果是 Firebug 用户的话( ...
  11. Epoll 模型详解

    Linux epoll模型 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的减少程序在大量并发连接中只有少量活跃的情况下的系统 ...
  12. block 实现原理(内存管理详解)(二)

    在以前,MRC环境下,使用block很可能会出现内存泄漏问题,并且在以往的面试中,一些接触比较久的程序员都会喜欢问到这个问题,block内存泄漏的问题! 下面,我来介绍一下,MRC下Block内存泄漏的一个问题 先随意创 ...
  13. Java内存溢出详解

    一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space----JVM Heap(堆)溢出 JVM在启动的时候会自动设置JVM Heap的值,其 ...
  14. Java虚拟机(JVM)中的内存设置详解

    一.简介 一般情况下,Java中分配的非空对象都是由Java虚拟机的垃圾收集器管理的,也称为堆内内存(on-heap memory).虚拟机会定期对垃圾内存进行回收,在某些特定的时间点,它会进行一次彻底的回收(full ...
  15. hdfs一致性模型详解

    文件系统的一致模型描述了对文件读写的数据可见性.HDFS为性能牺牲了一些POSIX请求,因此一些操作可能比想像的困难. 在创建一个文件之后,在文件系统的命名空间中是可见的,如下所示: 1. Path p = new Pa ...
  16. C语言.C++内存对齐问题详解

    这篇文章主要介绍了C语言.C++内存对齐问题详解,内存对齐的问题主要存在于理解struct和union等复合结构在内存中的分布,需要的朋友可以参考下 这也可以? #include <iostream> usi ...
  17. 字符串内存驻留机制详解示例

    字符串内存驻留机制详解示例,大家参考使用吧 //字符串的内存驻留机制 public static void Test() { //当有多个字符串变量包含了同样的字符串实际值时, //CLR可能不会为它们重复地分配内存,而 ...
  18. JavaScript的内存释放问题详解

    这篇文章主要介绍了JavaScript的内存释放问题详解的相关资料,需要的朋友可以参考下 本文详细的讲解了JavaScript及IE浏览器对内存的管理和释放的时机和方法,希望对前端开发人员有所帮助. 一个内存释放的实例 ...
  19. C语言:内存字节对齐详解

    C语言:内存字节对齐详解