Go语言中文网 为您找到相关结果 140

golang 内置函数new() 和struct{} 初始化的区别

new() 这是一个用来分配内存的内置函数,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配的 t 类型的零值的指针。 在golang的代码定义如下: func new(t Type) *Type strut{} 直接使用struct{} 来初始化strut时,返回的是一个struct类型的值,而不是指针两者是不一样的 两者对比代码如下: type Student struct{ id int name string } func main(){ var s_1 *Student = new(Student) s_1.id = 100 s_1.name = "cat" var s_2 Student = Student{id:1,name:"tom"} fmt.Println...阅读全文

博文 2015-06-17 20:03:41 happinessaflower

Go语言slice的那些坑

Go语言Google开发的适用于多核编程的语言。我感觉它像是C语言的现代版本,简单,并发支持友好,部署轻松。GO语言中保留关键字就只有25个,这也足以说明它的学习成本并不高。 然而,Go语言里面slice这个东西并不简单。初学者容易掉入坑中。此文件就试图把slice给讲解清楚。 下面先讲一下slice的一些基本特性。 1. slice内部有三个变量,分别是:ptr, len, cap ptr是用来存储数据的数组 cap是ptr数组的长度 len是实际数组的长度 2. 如何在初始化的时候,指定slice的长度? a := make([]int, 10) 这里make的时候,第2个参数,就是这个slice的长度。 这个时候它的capacity是多少呢? fmt.Println(cap(a)) 这...阅读全文

博文 2016-03-31 19:00:05 zhanchenxing

玩转Golang之Struct结构体

先介绍一下go语言的类型系统 Golang中的类型系统 类型系统是指一个语言的类型体系结构。一个典型的类型系统通常包含如下基本内容:  基础类型,如byte、int、bool、float等;  复合类型,如数组、结构体、指针等;  可以指向任意对象的类型(Any类型);  值语义和引用语义;  面向对象,即所有具备面向对象特征(比如成员方法)的类型;  接口。 Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。在需要的时候,你可以给任何类型(包括内置类型)“增加”新方法。而在实现某个接口时,无需从 该接口继承(事实上,Go语言根本就不支持面向对象思想中的继承语法),只需要实现该接口 要求的所有方法即可。任何类型都可以被Any类型引用。Any类型就是空接口,即inte...阅读全文

博文 2018-08-11 23:35:04 夏海社长

Go语言内幕(6):启动和内存分配初始化

本文由 伯乐在线 - yhx 翻译,黄利民 校稿。未经许可,禁止转载!英文出处:Siarhei Matsiukevich。欢迎加入翻译组。 《Go语言内幕(1):主要概念与项目结构》 《Go语言内幕(2):深入 Go 编译器》 《Go语言内幕(3):链接器、链接器、重定位》 《Go语言内幕(4):目标文件和函数元数据》 《Go语言内幕(5):运行时启动过程》 本文是 Golang 内部机制探索系列博客的后续。这个系列博客的目的是探索 Go 启动过程,这个过程也是理解 Go 运行时(runtime)的关键之处。本文中我们将一起去看看启动过程的第二个部分,分析参数是怎么被初始化的及其中有哪些函数调用等等。 启动顺序 我们从上次结束的地方继续。在 runtime.r0_to 函数中,我们还有一部分...阅读全文

博文 2016-06-01 14:49:26 伯乐在线

golang make()内置函数

内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型 make()函数在golang的代码如下: func make(t Type,size IntegerType) Type 使用make来创建slice,map,chanel说明如下: slice: var slice_ []int = make([]int,5,10) fmt.Println(slice_) var slice_1 []int = make([]int,5) fmt.Println(slice_1) var s...阅读全文

博文 2015-06-17 20:03:47 happinessaflower

Go的变量到底在堆还是栈中分配

Go的变量到底在堆还是栈中分配 2015-10-22 最近试着优化掉一些小对象分配,发现一个很诡异的问题:这段代码会在堆上分配对象! package main import ( "fmt" ) func main() { var a [1]int c := a[:] fmt.Println(c) } 看汇编代码 go tool compile -S test.golang "".main t=1 size=336 value=0 args=0x0 locals=0x98 0x0000 00000 (test.go:7) TEXT "".main(SB), $152-0 0x0000 00000 (test.go:7) MOVQ (TLS), CX 0x0009 00009 (test.go:...阅读全文

博文 2016-07-20 13:27:37 zenlife

golang学习之struct

结构体定义的一般方式如下: type identifier struct { field1 type1 field2 type2 ... } type T struct {a, b int} 也是合法的语法,它更适用于简单的结构体。 var t *T t = new(T) 变量 t 是一个指向 T的指针,此时结构体字段的值是它们所属类型的零值,使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针。 无论变量是一个结构体类型还是一个结构体类型指针,都使用同样的 选择器符(selector-notation) 来引用结构体的字段,即: type myStruct struct { i int } var v myStruct // v是结构体类型变量 var p *mySt...阅读全文

博文 2016-06-15 09:00:00 caiya928

go内存管理和垃圾收集简介

go语言的内存分两部分,一部分用作堆,供内存分配用,另一部分是bitmap,用来管理堆。两部分从同一地址开始,向高地址方向增长的是内存池,向低地址方向增长的是bitmap。 ##内存分配## 对于较大的内存申请,直接从堆上申请,释放时也直接返回给堆。 而当一个go routine申请小于32k字节的内存,则从go routine私有的内存池中分配内存。因为是私有的,所有在多数情况下,分配内存不需要上锁。如果私有内存池没有内存了,则需要向中心内存池申请内存,中心内存池是共享数据,此时需要上锁。如果中心内存池也没有内存了,则从堆里申请内存。 私有内存池和中心内存池里的内存都是按照大小分开管理的,这样,分配和释放内存都非常快,而且也不容易产生碎片。通常,中心内存池从堆上申请...阅读全文

golang中new和make区别

golang 中有两个内存分配机制 :new和make,二者有明显区别. new:用来初始化一个对象,并且返回该对象的首地址.其自身是一个指针.可用于初始化任何类型 make:返回一个初始化的实例,返回的是一个实例,而不是指针,其只能用来初始化:slice,map和channel三种类型 package main import ( "fmt" ) func main() { a := new([]int) fmt.Println(a) //输出&[],a本身是一个地址 b := make([]int, 1) fmt.Println(b) //输出[0],b本身是一个slice对象,其内容默认为0 } 通过这个例子可以看出,当对slice,map以及channel进行初始化时,使用make比n...阅读全文

Go语言内存分配器的实现

前几天断断续续的写了3篇关于Go语言内存分配器的文章,分别是Go语言内存分配器设计、Go语言内存分配器-FixAlloc、Go语言内存分配器-MSpan,这3篇主要是本文的前戏,其实所有的内容本可以在一篇里写完的,但内容实在太多了,没精力一口气搞定。本文将把整个内存分配器的架构以及核心组件给详细的介绍一下,当然亲自对照着翻看一下代码才是王道。 内存布局结构图 我把整个核心代码的逻辑给抽象绘制出了这个内存布局图,它基本展示了Go语言内存分配器的整体结构以及部分细节(这结构图应该同样适用于tcmalloc)。从此结构图来看,内存分配器还是有一点小复杂的,但根据具体的逻辑层次可以拆成三个大模块——cache,central,heap,然后一个一个的模块分析下去,逻辑就显得特别清晰明了了。位于结构图...阅读全文

博文 2014-11-13 21:58:15 skoo

go语言中var

go语言中定义变量使用关键字var,如:var x int=4 也可以写成x:=4; 在函数中,:= 简洁赋值语句在明确类型的地方,可以用于替代 var 定义。 (:= 结构不能使用在函数外,函数外的每个语法块都必须以关键字开始。) package main import ( "fmt" ) func main() { var x int = 4 fmt.Println(x)//输出4 fmt.Println(&x)//输出指针 //fmt.Println(*x) //错误 y := 4 fmt.Println(y)//输出4 fmt.Println(&y)//输出指针 //fmt.Println(*y) //错误 var v *int = new(int)//返回值为指针 fmt.Prin...阅读全文

Go语言内存分配器设计

Go语言的整个内存管理子系统主要由两部分组成——内存分配器和垃圾收集器(gc)。十一小长假期为了避开我泱泱大国的人流高峰,于是在家宅了3天把Go语言的内存分配器部分的代码给研究了一番,总的来说还是非常酷的,自己也学到了不少的东西,就此记录分享一下。整个内存分配器完全是基于Google自家的tcmalloc的设计重新实现了一遍,因此,想看看Go语言的内存分配器实现的话,强烈建议先读一读tcmalloc的介绍文档,然后看看Go runtime的malloc.h源码文件的注释介绍,这样基本就大概了解Go语言内存分配器的设计了。 Go的内存分配器主要也是解决小对象的分配管理和多线程的内存分配问题。(后面提到的内存分配器都是指代的Go语言实现的内存分配器)。内存分配器以32k作为对象大小的定夺标准,小...阅读全文

博文 2014-11-12 17:25:06 skoo

Go语言数据结构

当向一个新程序员解释Go语言时,我发现如果解释Go的数据是如何在内存中表示的,将有助于建立编写高效程序的良好直觉。 转载地址:http://www.open-open.com/lib/view/open1390373069882.html 基础类型 让我们从一些简单的例子开始: 变量i是int类型,在内存中占用一个32位的存储单位。(上图拿32位系统来举例;对以上的例子,只有指针才会在64位的机器上占用更多的空间——int始终是32位——然而我们仍然可以选择64位的系统。) 变量j是int32类型,因为它经过了显式的类型转化。尽管i和j有着同样的内存布局,但它们的类型是不一样的:像这样的赋值i = j会产生类型异常,必须通过显式的类型转换:i = int(j) 。 变量f是个浮点类型,上例中...阅读全文

博文 2015-04-09 11:00:01 Decadent_2014

服务计算 - 1 VirtualBox配置私有云

VirtualBox配置私有云 初始准备 AMD处理器电脑需要开启AMD-V Intel处理器电脑需要开启Intel-VT 下载VirtualBox并安装 下载CentOs7(可以选择普通版也可以选择最小ISO) 创建Linux虚拟机 配置内网互联用的网卡 新建网卡: VirtualBox菜单 :管理 -> 主机网络管理器,创建一块虚拟网卡 配置参数: 网址分配:192.168.100.1/24,在主机 windows 命令行窗口输入 ipconfig 就可以看到 VirtualBox Host-Only Network #?: 的网卡 安装CentOs 新建系统: 分配资源:分配内存和处理器,建议分配1/3左右的资源给虚拟机,虚拟机硬盘最好大于30GB。 第一块网卡必须是 NAT;第二块网...阅读全文

Go中实现手动内存分配的坑

Go中实现手动内存分配的坑 2016-07-10 你一定想到过,分配一块大的内存,然后从里面切小的对象出来,手动管理对象分配。分配的开销非常小,就是offset加一下。尤其是有些场景,释放时直接把offset重置,就可以重用这块空间了。实现手动内存分配的好处是,减少小对象数目,从而减少垃圾回收时的扫描开销,降低延迟和提升整个性能。 想到不代表做过,做过会踩坑,这篇文章会把你可能要踩的坑都说一遍。不过先说结论:别这么干,不作死就不会死! TL;DR 扩容 开始很容易想用make([]byte)分配空间,如果大小不够时,还可以进行扩容。这是第一个陷阱。 不要append,别让它扩容。一旦发生扩容,会分配一块新的空间,而旧的slice将不再有任何变量引用它,于是会被垃圾回收掉。等等!之前分配的对象...阅读全文

Go 语言的内存管理

这篇博客是我在维尔纽斯的 [Go Meetup](https://www.meetup.com/Vilnius-Golang/events/249897910/) 演讲的总结。如果你在维尔纽斯并且喜欢 Go 语言,欢迎加入我们并考虑作演讲 在这篇博文中我们将要探索 Go 语言的内存管理,首先让我们来思考以下的这个小程序: ```go func main() { http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) }) http.ListenAndServe(":8080", nil) }...阅读全文

博文 2018-09-20 22:25:03 polaris

Golang引用类型

引用类型包含 slice、map、channel 内置函数:new 为其分配零值内存 并返回指针 make 为其分配内存初始化结构 并返回对象 package main import ( "fmt" ) func main() { a := make([]int, 3) a[1] = 10 b := new([]int) b[1] = 20 //error : invalid operation: b[1] (type *[]int does not support indexing) ...阅读全文

博文 2016-09-12 12:00:34 lt695981642

Golang实现大数乘法

大数乘法,简单的说,就是把小学学的列竖式计算的方法进行了实现。这其实也就是个乘法分配率的变形。 5 * 12 = 5 * (2 + 10) = 5 * 2 + 5 * 10 所以第二行竖式,12的十位1与5相乘的时候,需要再最后空一位,其实是在最后省略了一个0。十位就是省略一个0,也就是左移一位,那么百位就是左移两位。以此类推。 通过代码实现,相乘的两个数就不能用整形表示了,因为存不了很大的整数。需要用字符串表示。按位相乘,最后把结果错位相加就行。乘法的结果等于乘数的位数,所以可以申请一个和乘数位数相同的数组,然后错位相加即可。但是这样太麻烦了。 乘法是从个位开始,但是遍历字符串是从最高为开始的,所以要首先将输入字符串反转。用i表示被乘数的遍历索引,j表示乘数的索引。前面说了左移的位数和乘数...阅读全文

Go语言内存分配器-FixAlloc

昨天写了一篇Go语言内存分配器设计,记录了一下内存分配器的大体结构。在介绍内存分配器的核心实现前,本文先介绍一下内存分配器中一个工具组件——FixAlloc。FixAlloc称不上是核心组件,只是辅助实现整个内存分配器核心的一个基础工具罢了,由此可以看出FixAlloc还是一个比较重要的组件。引入FixAlloc的目的只是用来分配MCache和MSpan两个特定的对象,所以内存分配器中有spanalloc和cachealloc两个组件(见《Go语言内存分配器设计》的图)。MCache和MSpan两个结构在malloc.h中有定义。 定义在malloc.h文件中的FixAlloc结构如下,比较关键的三个字段是alloc、list和chunk,其他的字段主要都是用来统计一些状态数据的,比如分配了...阅读全文

博文 2014-11-13 21:58:14 skoo

Go语言内存分配器-MSpan

MSpan和FixAlloc一样,都是内存分配器的基础工具组件,但和FixAlloc没太大的交集,各自发挥功效而已。span(MSpan简称span)是用来管理一组组page对象,先解释一下page,page就是一个4k大小的内存块而已。span就是将这一个个连续的page给管理起来,注意是连续的page,不是东一个西一个的乱摆设的page。为了直观形象的感受一下span,还是得画个图吧,图形是最好的交流语言。 MSpan结构定义在malloc.h头文件中,代码如下: struct MSpan { MSpan *next; // in a span linked list MSpan *prev; // in a span linked list PageID start; // start...阅读全文

博文 2014-11-13 21:58:14 skoo

go语言学习之路五:Go语言内存分配机制make&new

Go有两种分配内存的机制,规则很简单,下面来简单介绍一下。1、new函数New()函数可以给一个值类型的数据分配内存(不知道什么是值类型请前往切片那一部分),调用成功后返回一个初始化的内存块指针,同时该类型被初始化为0值,原型定义:func new(Type) * Typenew是一个分配内存的内置函数,但是不同于其他语言中new所做的工作,它只是将内存清零,而不是初始化内存。2、make函数Make()函数用于给引用类型分配内存空间,比如:slice,map,channal等,这里需要注意的一点是make()创建的是一个引用类型的对象,而不是一个内存空间的指针。Make()函数原型:func make(Type,size IntegerType)Type参数Type必须是一个引用类型(sl...阅读全文

Go语言select的内存分配情况

最近看了Go runtime中关于select的实现(select in Go’s runtime),发现select语句位于for循环之内执行的时候,每一遍循环都需要在底层runtime中经历malloc对象到free对象的过程,我认为这个频繁的内存分配和释放的代价并不小,至少内存不是处于一种稳定的状态。因此,我实际的测试一把使用select来操作channel和不使用select操作channel两种情况下的内存情况。 测试过程都是运行程序3分钟,每一次循环sleep 1秒钟,每10秒钟采集一下内存使用情况的数据。为了更直观的感受,我使用goplot工具把采集到的内存数据绘制成了图表。 使用select 测试代码:https://gist.github.com/skoo87/672715...阅读全文

[Go] --- 指针和内存分配

Email : hahayacoder@gmail.com 1 Go语言中的指针和C语言中在使用上几乎没有什么差别,熟悉C语言应该很容易掌握,下面是Go语言中使用指针的代码 package main import "fmt" func main() { var value int = 1 //指向int型的指针 var pInt *int = &value //打印相关信息 fmt.Printf("value = %d \n pInt = %d \n *pInt = %d \n", value, pInt, *pInt) //通过指针修改指针指向的值 *pInt = 222 fmt.Printf("value = %d \n pInt = %d \n *pInt = %d \n", valu...阅读全文

博文 2014-10-10 12:00:01 qiurisuixiang

golang对象内存分配

一、分配对象(源码) // 分配对象内存入口 func newobject(typ *_type) unsafe.Pointer { return mallocgc(typ.size, typ, true) } // 分配指定object的大小(bytes数) // 当分配的object大小 <= 32kb 使用每个P本地缓存空闲列表即可 // > 32 kB 直接堆上进行分配. func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { // 零长度对象 if size == 0 { return unsafe.Pointer(&zerobase) // 在heap上分配,则都指向预设的同一全局变量(零长度...阅读全文

博文 2019-01-07 19:34:46 神奇的考拉

为什么说go语言中的string是不可变的?

```go s := "foobar阿斯蒂芬" fmt.Println(s) fmt.Println(&s) s = "qweqweqweqweqwe" fmt.Println(s) fmt.Println(&s) ``` 这个不可变到底指的是啥意思?上面的代码不就使s这个string变量改变了吗?而且s的地址也没有变化(说明没有给s重新分配内存),那这样看来,s就是可变的呀,实在不懂,求解惑 ...阅读全文

golang中new和make区别

golang 中有两个内存分配机制 :new和make,二者有明显区别. new:用来初始化一个对象,并且返回该对象的首地址.其自身是一个指针.可用于初始化任何类型 make:返回一个初始化的实例,返回的是一个实例,而不是指针,其只能用来初始化:slice,map和channel三种类型 package main import ( "fmt" ) func main() { a := new([]int) fmt.Println(a) //输出&[],a本身是一个地址 b := make([]int, 1) fmt.Println(b) //输出[0],b本身是一个slice对象,其内容默认为0 } 通过这个例子可以看出,当对slice,map以及channel进行初始化时,使用make比n...阅读全文

博文 2015-06-17 20:02:37 chenbaoke

从源码讲解 golang 内存分配

## 引言 golang 是谷歌2009年发布的开源编程语言,截止目前go的release版本已经到了1.12,Golang 语言专门针对多处理器系统应用程序的编程进行了优化,使用 Golang 编译的程序可以媲美 C /C++代码的速度,而且更加安全、支持并行进程。和其他“高级语言”一样,golang同样有一套自己的内存管理机制,自主的去完成内存分配、垃圾回收、内存管理等过程,从而避免频繁的向操作系统申请、释放内存,有效的提升go语言的处理性能。由于篇幅有限,本文重点针对golang1.12.6版本就内存分配情况进行一下梳理和讲解。golang的内存管理是基于tcmalloc模型设计,但又有些差异,局部缓存并不是分配给进程或者线程,而是分配给P(Processor);golang的GC是s...阅读全文

博文 2019-08-11 01:00:24 polaris

多线程并发下载器-gorc

gorc是类wget多线程下载器,支持直接从资源url并发获取资源 项目地址:https://github.com/V-I-C-T-O-R/gorc 使用说明: 1.手动选择模式和自动分配模式,参数:manual,默认为false/自动 2.指定并发线程数,参数:thread,默认为5 3.指定下载的url,参数:url 4.指定分块下载的块大小,参数:blockSize,例如,默认1代表16m,2代表32m,4代表64m,以此类推 5.指定分块下载失败后尝试次数,参数:attempt,默认为3 6.指定文件存放位置,参数:root,默认为项目的lib目录 7.程序使用秩序调用gorc.Download(url string)函数即可 ...阅读全文

设计模式-适配器模式(Go语言描述)

在上一篇博客设计模式-策略模式(Go语言描述)中我们用最简单的代码用go语言描述了设计模式中的策略模式,用最简单的实例来描述相信可以让初学者可以很轻松的掌握各种设计模式。继上篇博客,我们接着用同样简单的代码来了解一下适配器模式。 适配器模式介绍 说起适配器模式,相信很多做android的同学第一印象就是AdapterView的Adapter,那它是干嘛用的呢?为什么要叫adapter呢?要了解这个问题,我们首先来看看适配器模式的定义: 将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。——Gang of Four 恩,看起来好像有点迷糊,举个例子吧: 我电脑的电源是三个插头(也就是有地线)的那种,不知道为啥学校的插座都是两个插孔的...阅读全文

博文 2016-02-01 11:00:02 qibin0506

Go 逃逸分析

文地址:Go 逃逸分析 什么是逃逸分析 堆和栈 要理解什么是逃逸分析会涉及堆和栈的一些基本知识,如果忘记的同学我们可以简单的回顾一下: 堆(Heap):一般来讲是人为手动进行管理,手动申请、分配、释放。堆适合不可预知大小的内存分配,这也意味着为此付出的代价是分配速度较慢,而且会形成内存碎片。 栈(Stack):由编译器进行管理,自动申请、分配、释放。一般不会太大,因此栈的分配和回收速度非常快;我们常见的函数参数(不同平台允许存放的数量不同),局部变量等都会存放在栈上。 栈分配内存只需要两个CPU指令:“PUSH”和“RELEASE”,分配和释放;而堆分配内存首先需要去找到一块大小合适的内存块,之后要通过垃圾回收才能释放。 通俗比喻的说,栈就如我们去饭馆吃饭,只需要点菜(发出申请)--》吃吃吃...阅读全文

博文 2019-07-14 16:32:37 WilburXu

go map (映射-类似其它语言的集合)

map介绍 map是key-value数据结构,又称为字段或者关联数组。类似其它编程语言的集合。 基本语法 var map的变量名 map(关键字)[keyType]valueType 1、key可以是什么类型 golang中的map可以是多种类型,比如 bool,数字,string,指针,channel(管道),还可以是只包含前面几个类型的 接口,结构体,数组, 通常是 int,string slice map function 不可做为key的数据类型。 2、valueType可以是什么类型 valueType的类型和key基本一样,通常为:数字(整数,浮点数),string,map,struct map的声明 var a map[string]string var a map[stri...阅读全文

博文 2019-04-02 12:34:40 StevenQin

Golang Map 实现 (二) map 的创建

本文在golang map 数据结构的基础上,学习一个make 是如何构造的。 map 创建示例 在golang 中,初始化一个map 算是有两种方式。 example1Map := make(map[int64]string) example2Map := make(map[int64]string, 100) 第一种方式默认不指定map的容量,第二种会指定后续map的容量估计为100,希望在创建的时候把空间就分配好。 当make创建map时,底层做了什么 对于不同的初始化方式,会使用不同的方式。下面是提供的几种初始化方法: // hint 就是 make 初始化map 的第二个参数 func makemap(t *maptype, hint int, h *hmap) *hmap fun...阅读全文

博文 2020-04-30 10:32:40 搬砖程序员带你飞

图解Go内存分配器

本文翻译自《A visual guide to Go Memory Allocator from scratch (Golang)》。 当我刚开始尝试了解Go的内存分配器时,我发现这真是一件可以令人发疯的事情,因为所有事情似乎都像一个神秘的黑盒(让我无从下手)。由于几乎所有技术魔法都隐藏在抽象之下,因此您需要逐一剥离这些抽象层才能理解它们。 在这篇文章中,我们就来这么做(剥离抽象层去了解隐藏在其下面的技术魔法)。如果您想了解有关Go内存分配器的知识,那么本篇文章正适合您。 一. 物理内存(Physical Memory)和虚拟内存(Virtual Memory) 每个内存分配器都需要使用由底层操作系统管理的虚拟内存空间(Virtual Memory Space)。让我们看看它是如何工作的吧。...阅读全文

Go语言内存分配器-FixAlloc

Go语言内存分配器-FixAlloc 09 October 2013 skoo 阅读 918 次 1 人喜欢 0 条评论 收藏 昨天写了一篇Go语言内存分配器设计,记录了一下内存分配器的大体结构。在介绍内存分配器的核心实现前,本文先介绍一下内存分配器中一个工具组件——FixAlloc。FixAlloc称不上是核心组件,只是辅助实现整个内存分配器核心的一个基础工具罢了,由此可以看出FixAlloc还是一个比较重要的组件。引入FixAlloc的目的只是用来分配MCache和MSpan两个特定的对象,所以内存分配器中有spanalloc和cachealloc两个组件(见《Go语言内存分配器设计》的图)。MCache和MSpan两个结构在malloc.h中有定义。 定义在malloc.h文件中的Fi...阅读全文

博文 2016-04-11 08:00:04 caoshulin1989

Go GC

大家好,我是 Okada([@ocadaruma](https://twitter.com/ocadaruma)),LINE 广告平台团队的成员。我对 Go 的 GC (垃圾收集器)有点感兴趣,甚至还促使我专门写一篇关于它的博客。Go 是一门由 Google 开发,并且支持垃圾收集的编程语言。Go 通过[管道](https://tour.golang.org/concurrency/2) 支持并发。很多的公司,包括 Google,都在使用 Go,LINE 也用 Go 来开发工具和服务。 ## Go GC 用 Go,你可以很容易地创建出低延时的应用。Go GC 似乎比其他语言的运行时要简单得多。对于 [Go 1.10](https://golang.org/doc/go1.10) 版本,它的垃...阅读全文

博文 2018-11-07 10:28:34 gogeof

[go语言]Buffered channel、slice和mutex的简单性能测试

测试代码: package main import ( "fmt" "runtime" "sync" "time" ) const COUNT = 1000000 func bench1(ch chan int) time.Duration { t := time.Now() for i := 0; i < COUNT; i++ { ch <- i } var v int for i := 0; i < COUNT; i++ { v = <-ch } _ = v return time.Now().Sub(t) } func bench2(s []int) time.Duration { t := time.Now() for i := 0; i < COUNT; i++ { s[i] = ...阅读全文

博文 2014-11-02 15:06:15 stevewang

Go手动内存分配

2013-10-27 Go手动内存分配 Go手动内存分配 用Go的时候,有时候又想自己管理内存。所以决定写个手动内存管理的包吧。就当无聊练练手... 总体设计 两级分配。较大内存以页为单位分配,每页4k。分配出去的大块内存只能是1页,2页,3页...较小内存使用buddy算法结合分配池的方式进行分配。buddy算法主要是方便回收,对于各种不规则大小则分别维护一个free的链表。 整体上基本类似于Go本身使用的内存管理算法,除了没有引入垃圾回收标记信息,以及对小对象使用buddy分配算法。 buddy算法 管理结点使用的内存跟最小最大结点相关。如果最小单元太小,则浪费过多的管理结点。管理结点数目=最小单元数目*2 如果最大单元过大,则需要用更长的整型来记录大小,单个管理结点的大小增加。 bud...阅读全文

博文 2015-03-17 10:25:55 zenlife

golang slice 和 string 重用

相比于 c/c++,golang 的一个很大的改进就是引入了 gc 机制,不再需要用户自己管理内存,大大减少了程序由于内存泄露而引入的 bug,但是同时 gc 也带来了额外的性能开销,有时甚至会因为使用不当,导致 gc 成为性能瓶颈,所以 golang 程序设计的时候,应特别注意对象的重用,以减少 gc 的压力。而 slice 和 string 是 golang 的基本类型,了解这些基本类型的内部机制,有助于我们更好地重用这些对象 slice 和 string 内部结构 slice 和 string 的内部结构可以在 $GOROOT/src/reflect/value.go 里面找到 type StringHeader struct { Data uintptr Len int } type...阅读全文

博文 2018-03-17 17:34:37 hatlonely

[翻译]Go tip(2013-08-23)带来的变化

Dominik Honnef(之前搞错成 Russ Cox 了)在 What’s happening in Go tip (2013-08-23) 中介绍了一些关于 Go 语言的一些变化。这些变化包含了语法、性能、潜在风险和工具链。并且,这些新的东西可能会随着 Go 1.2 版本一同发布。为了方便中文读者,翻译在此。 ————翻译分隔线———— Go tip(2013-08-23)带来的变化 上周我发布了关于 Go tip 的变化的系列文章的第一篇。得到了大量的肯定,因此这是第二篇。感谢你的支持,并且希望你能像喜欢第一篇文章一样喜欢本文。 有哪些变化 这次,将对以下内容进行探讨: 关于切片的新语法 性能改进 快速的,常量时间的 P-256 椭圆曲线 godoc 到哪去了? 关于切片的新语法 ...阅读全文

博文 2014-10-09 16:20:11 mikespook

golang atomic 32位机器问题

测试过程中发现一个atomic.AddInt64()报内存错误 32位window,linux下都不能正常运行 示例代码: package main import( "fmt" "sync/atomic" ) type item struct{ //c int32 d int32 a int64 } type Obj struct{ list map[string]*item } func (ob *Obj)Init(){ ob.list = make(map[string]*item) ob.list["a"] = &item{} } func (ob *Obj)Add(){ atomic.AddInt64(&ob.list["a"].a,12) fmt.Println(ob.list["...阅读全文

[go语言]内存分配器性能测试

在C/C++里,自己动手实现内存分配器是很常见的事情,写过几年C/C++程序的人可能都做过这样的事情。这其中很重要的一个原因是C/C++不支持垃圾回收。但是既然go语言已经支持垃圾回收,还有必要自己去写一个内存分配器吗?我们做一个简单的测试看看结果怎么样。 测试平台: OS: ubuntu 12.04 x86_64 CPU: i5 2.27G MEMORY: 8G // ben1.go 自己实现内存分配器 package main type Pool struct { buf []byte } func (p *Pool) alloc(size int) []byte { if len(p.buf) < size { l := 1024 * 1024 for l < size { l += ...阅读全文

博文 2014-10-30 18:07:21 stevewang

[go语言]一种自适应资源分配器的实现

在上一篇博文《利用缓冲信道来实现网游帐号验证消息的分发和等待》中提到提到利用缓冲信道来实现数据包的分发和等待,并给出了一个原型实现。但是其中的缓冲信道有一个不足,即只能允许一定数量的goroutine在同时使用SendAndReceive函数等待消息的分发;如果有更多的goroutine需要等待消息,则必须等其他goroutine获得消息并释放信道以后自己才能发送数据包并等待回应。这个不足在高并发时限制了系统的吞吐量。 为了解决这个问题,本文提供一种自适应的信道分配器的实现作为一种解决方案。因为信道也可以换成别的资源,所以认为它本质上是一种资源分配器。这个自适应资源分配器的原理是: 1.预先分配一定数量的资源放到缓冲信道(缓冲池)里,以便在申请资源时能够快速获得资源 2.如果申请资源时缓冲池...阅读全文

博文 2014-11-02 15:03:54 stevewang

golang内存管理

几个关键数据结构 mspan 由mheap管理的页面,记录了所分配的块大小和起始地址等 mcache 与P(可看做cpu)绑定的线程级别的本地缓存 mcenter 全局空间的缓存,收集了各种大小(67种)的span列表 mheap 分配内存的堆分配器,以8kb进行页管理 fixalloc 固定尺寸的堆外对象空闲列表分配器,用来管理分配器的存储 内存分配逻辑 如果object size>32KB, 则直接使用mheap来分配空间; 如果object size<16Byte, 则通过mcache的tiny分配器来分配(tiny可看作是一个指针offset); 如果object size在上面两者之间,首先尝试通过sizeclass对应的分配器分配; 如果mcache没有空闲的span, 则向mc...阅读全文

博文 2019-08-09 00:32:55 SuperGopher

为什么 Go 还没实现分代和紧凑 GC

本文译自 Google 论坛(golang-nuts)版权@归原文所有. 有人在论坛里面问: 为什么 Golang 垃圾回收器不实现分代和紧凑 gc ? Ian Lance Taylor 的回复: 这已经在过去讨论过了. 忽略细节, 紧凑(compacting) GC 的基本优点是: 避免碎片, 以及; 允许使用简单而有效的凹凸分配器(bump allocator). 但是, 现代的内存分配算法, 象 Go 运行时使用的基于 tcmalloc 的方案基本上没有碎片问题. 而凹凸分配器对于 Go 这样需要锁的多线程程序中的单线程程序是简单有效的. 一般来说, 这可能更多有效地使用一组每个线程缓存来分配内存, 而在这一点上你已经失去了凹凸分配器的优势. 所以我会断言, 一般来说有很多注意事项导致...阅读全文

golang 注释命令

protoc //go:generate protoc -I ../routeguide --go_out=plugins=grpc:../routeguide ../routeguide/route_guide.proto 压测 -bench 指定方法名字后缀,-bench="." 测试 全部方法(Benchmark_Rar:-bench=Rar) -benchtime 自定义测试时间 -benchmem 参数以显示内存分配情况 //go:generate go test main_test.go -v -bench=Rar -benchtime=60s -benchme...阅读全文

博文 2019-04-16 09:34:42 Feng_Sir

Go语言内存分配机制

前言: 本文是学习<> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请注明出处! Go语言有两种内存分配机制 , 分别是内置函数 new() 和make(). - new() - 定义: func new(Type) * Type - 返回值是一个内存块指针 - new() 是一个内置函数, 不同于其他语言中的new操作符, 它只将内存清零, 而不是初始化内存. - make() - 定义: func make(Type, size IntegerType) Type - 在调用make() 函数时, Type必须是引用类型 (Slice , Map 或 Channel), Intege...阅读全文

mysql5.6 rpm安装后运行错误

mysql5.6.16,rpm安装后运行,日志内出现以下错误: 2014-01-30 00:52:59 17504 [Warning] Buffered warning: Performance schema disabled (reason: init failed). 2014-01-30 00:52:59 17504 [Note] Plugin 'FEDERATED' is disabled. 2014-01-30 00:52:59 17504 [Note] InnoDB: The InnoDB memory heap is disabled 2014-01-30 00:52:59 17504 [Note] InnoDB: Mutexes and rw_locks u...阅读全文

Go基础系列:nil channel用法示例

Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 当未为channel分配内存时,channel就是nil channel,例如var ch1 chan int。nil channel会永远阻塞对该channel的读、写操作。 nil channel会阻塞对该channel的所有读、写。所以,可以将某个channel设置为nil,进行强制阻塞,对于select分支来说,就是强制禁用此分支。 以下是一个nil channel的示例: package main import ( "fmt" "math/rand" "time" ) // 不断向channel c中发送[0,10...阅读全文

博文 2018-11-23 09:12:12 f-ck-need-u

go文件操作

go语言支持的文件操作很多 1、传统的文件操作 导入文件操作需要的包 import "os" 1、文件的打开 f := os.Open(filepath) 2、文件的读取 f.Read([]byte) 3、文件的关闭 f.Close() 这里写代码片 openfile, err := os.Open(“test.go”)//正确打开文件返回err := nil //这里如果文件打开异常,则抛出错误 if err != nil { //panic函数会终止程序的运行,并且打印错误相当于C/C++中的assert()函数 panic(“open file error”) } //defer相当于C++中的析构函数,在程序结束之前,运行其后的函数 defer openfile.Close() //...阅读全文

博文 2016-05-27 15:00:03 u010165367

1.9 新特性预览:Logging, interfaces, and allocation

该文翻译自:http://commaok.xyz/post/interface-allocs/几个星期前,Peter Bourgon在golang-dev开了一个关于标准化日志记录的帖子。 日志很常用,因此性能很快提升。 go-kit日志包使用结构化日志,接口如下:type Logger interface { Log(keyvals ...interface{}) error}调用代码:logger.Log("transport", "HTTP", "addr", addr, "msg", "listening")请注意,进入日志调用的所有内容都将转换为interface{}。 这意味着它分配了不少内存。与另一个结构化日志库zap进行比较。 Zap为了避免内存分配和interface{}使...阅读全文

博文 2017-02-13 02:42:51 方圆