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

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-09-04 12:05:49 hatlonely的小站

Go内存分配那些事,就这么简单!

文链接:https://mp.weixin.qq.com/s/3g... 新老朋友好久不见,我是大彬,这篇文章准备了很久,不是在拖延,而是中间做了一些其他事情,耽搁了一些。 这篇文章主要介绍Go内存分配和Go内存管理,会轻微涉及内存申请和释放,以及Go垃圾回收。 从非常宏观的角度看,Go的内存管理就是下图这个样子,我们今天主要关注其中标红的部分。 友情提醒:文章有点长,建议先收藏,后阅读,绝对是学习内存管理的好资料。 本文基于go1.11.2,不同版本Go的内存管理可能存在差别,比如1.9与1.11的mheap定义就是差别比较大的,后续看源码的时候,请注意你的go版本,但无论你用哪个go版本,这都是一个优秀的资料,因为内存管理的思想和框架始终未变。 Go这门语言抛弃了C/C++中的开发者管理...阅读全文

【深度知识】Go语言:启动和内存分配初始化

本文是 Golang 内部机制探索系列博客的后续。这个系列博客的目的是探索 Go 启动过程,这个过程也是理解 Go 运行时(runtime)的关键之处。本文中我们将一起去看看启动过程的第二个部分,分析参数是怎么被初始化的及其中有哪些函数调用等等。 启动顺序 我们从上次结束的地方继续。在 runtime.r0_to 函数中,我们还有一部分没有分析: CLD // convention is D is always left cleared CALL runtime·check(SB) MOVL 16(SP), AX // copy argc MOVL AX, 0(SP) MOVQ 24(SP), AX // copy argv MOVQ AX, 8(SP) CALL runtime·args(...阅读全文

博文 2019-08-13 01:32:47 笔名辉哥

C实现的vector动态数组

动态数组vector是日常业务代码最常用的数据结构,大多数高级语言都提供了动态数组的实现, 如c++中的std::vector, python和golang中的[]。然而在c中没有提供这一重要的轮子,我们在这里一步一步构建一个c中的vector,可能不能在正式场景中使用,但是可以作为一个研习数据结构和内存分配的工具。 创建文件vector.h, vector.c,定义vector数据结构和init函数 //vector.h #ifndef VECTOR_H_ #define VECTOR_H_ #define INIT_CAP 10 typedef struct vector{ int cap; int len; void **items; }vector; void init_vec...阅读全文

博文 2019-04-21 11:34:40 Kevin_e8f2

tcmalloc 介绍

go的内存管理和tcmalloc(thread-caching malloc)很像,不妨先看看tcmalloc的实现。 tcmalloc是什么tcmalloc是google推出的一种内存分配器,常见的内存分配器还有glibc的ptmalloc和google的jemalloc。相比于ptmalloc,tcmalloc性能更好,特别适用于高并发场景。 tcmalloc具体策略tcmalloc分配的内存主要来自两个地方:全局缓存堆和进程的私有缓存。对于一些小容量的内存申请试用进程的私有缓存,私有缓存不足的时候可以再从全局缓存申请一部分作为私有缓存。对于大容量的内存申请则需要从全局缓存中进行申请。而大小容量的边界就是32k。缓存的组织方式是一个单链表数组,数组的每个元素是一个单链表,链表中的每个元素...阅读全文

博文 2017-07-02 19:24:21 Tao Kelu

Rust内存分配器的不同行为

本文出自Rust内存分配器的不同行为,同步于Rust中文社区专栏:Rust内存分配器的不同行为 ,本文时间:2019-01-04, 作者:Pslydhh,简介:Pslydhh 欢迎加入Rust中文社区,共建Rust语言中文网络!欢迎向Rust中文社区专栏投稿,投稿地址 ,好文在以下地方直接展示, 欢迎访问Rust中文论坛,QQ群:570065685 Rust中文社区首页 Rust中文社区文章专栏 对于如下的代码,采用nightly version: use std::sync::mpsc; use std::thread; fn main() { const STEPS: usize = 1000000; thread::sleep(std::time::Duration::from_mil...阅读全文

博文 2019-01-04 23:34:46 krircc

数组与切片

[原文链接](https://yc90s.github.io/2017/11/20/%E6%95%B0%E7%BB%84%E4%B8%8E%E5%88%87%E7%89%87/) ## 数组 ### 定义 数组是一组同类型数据的集合,它是**值类型**,通过从0开始的下标索引访问元素值。初始化后**数组长度是固定的**,无法修改其长度。当作为方法的入参传入时將复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分。 ### 初始化 - 长度为5的数组,其元素值依次为:1, 2, 3, 4, 5 ``` [5]int{1, 2, 3, 4, 5} ``` - 长度为5的数组,其元素值依次为:1, 2, 0, 0, 0. 在初始化时没有指定初值的元素將会赋值为其元素类型的默认值,int是0...阅读全文

博文 2017-11-21 12:36:16 yc90s

Go 语言内存分配器的实现原理

本文节选自 Go 语言设计与实现的 7.1 节。阅读全书:https://draveness.me/golang/ 程序中的数据和变量都会被分配到程序所在的虚拟内存中,内存空间包含两个重要区域 — 栈区(Stack)和堆区(Heap)。函数调用的参数、返回值以及局部变量大都会被分配到栈上,这部分内存会由编译器进行管理;不同编程语言使用不同的方法管理堆区的内存,C++ 等编程语言会由工程师主动申请和释放内存,Go 以及 Java 等编程语言会由工程师和编译器共同管理,堆中的对象由内存分配器分配并由垃圾收集器回收。 不同的编程语言会选择不同的方式管理内存,本节会介绍 Go 语言内存分配器,详细分析内存分配的过程以及其背后的设计与实现原理。 7.1.1 设计原理 内存管理一般包含三个不同的组件,分...阅读全文

博文 2020-03-08 15:32:47 draveness

Golang learning 数组 切片(slice)

数组 切片(slice) 数组是值类型,切片是引用类型,虽然很像,但是本质不同。使用时注意不要用错 var a [2]int 数组初始化没有赋值,打印结果 [] 空值,不为nil fmt.Print(a) a := [2]int{1,2} 数组初始化赋值 fmt.Print(a) a := [2]int{1,2} 数组初始化赋值,指定数组个数 fmt.Print(a) a := [4]int{1,2:3} 数组指定下标位置初始化,未指定下标值默认0(type []int),打印结果[1 0 3] fmt.Print(a) a := [...]int{1,2} 编译器会按照数量确定数组长度 fmt.Print(len(a)) type Person struct { struct 类 name...阅读全文

博文 2019-05-13 19:34:52 wangyongyue

go内存分配机制-TCMalloc

golang的内存采用了TCMalloc 这种分配机制。go是在多种语言诞生N多年之后,才由几个大神开发的。每种语言都有自己的内存分配机制,那么作为后起之秀,go为什么选用TCMalloc呢?因为TCMalloc(Thread-Cache Malloc) 在内存分配上性能做的更好,而且对内存的利用率也有所提高。先简单说一下TCMalloc在这两方面是如何做到的? 性能提升主要从两点来看,第一点线程内部小对象的使用不存在锁竞争,减少了竞争带来的性能开销; 第二点内存大对象的分配直接在堆上,并且采用了自旋锁,某个线程等待另一个线程释放锁的时候,不会像传统互斥锁一样由运行态转到休眠态,等待线程一会处于忙等待,减少了线程状态的切换。 在内存利用率方面,区分了线程、central、heap三级,线程之...阅读全文

博文 2019-03-14 08:34:40 17freedom

DAY5 GOLANG(五)关于时间的函数

时间和日期的相关函数1)时间和日期函数now :=time.Now() //获取当前时间,可以通过now获取当前时间的年月日,时分秒fmt.Printf("now=%v \nnow type=%T\n",now,now)fmt.Printf("年=%v\n",now.Year())fmt.Printf("月=%v\n",now.Month())fmt.Printf("月=%v\n",int (now.Month())) //外面加一个int,把输出转换为整型fmt.Printf("日=%v\n",now.Day())fmt.Printf("时=%v\n",now.Hour())fmt.Printf("分=%v\n",now.Minute())fmt.Printf("秒=%v\n",now.S...阅读全文

博文 2019-10-31 22:33:35 aside section._1OhGeD

Golang之变量去哪儿?

写过C/C++的同学都知道,调用著名的malloc和new函数可以在堆上分配一块内存,这块内存的使用和销毁的责任都在程序员。一不小心,就会发生内存泄露,搞得胆战心惊。 切换到Golang后,基本不会担心内存泄露了。虽然也有new函数,但是使用new函数得到的内存不一定就在堆上。堆和栈的区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成的。 一个变量是在堆上分配,还是在栈上分配,是经过编译器的逃逸分析之后得出的结论。 这篇文章,就将带领大家一起去探索逃逸分析——变量到底去哪儿,堆还是栈? 什么是逃逸分析 以前写C/C++代码时,为了提高效率,常常将pass-by-value(传值)“升级”成pass-by-reference,企图避免构造函数的运行,并且直接返回一个指针。 你一...阅读全文

博文 2019-03-01 20:34:40 Stefno

????设计模式-适配器模式-Adapter

????适配器模式-Adapter原文地址:https://github.com/mumushuiding/golang-design-pattern/tree/master/01_Adapter把一个"错误"的接口????转换为希望的形式。它处理的是????匹配问题。⚡️ 类图适配器模式中,建造一个适配器有两种可能性:⚡️ 基于类的适配器(简称类适配器);???? 基于对象的适配器(简称对象适配器);​​ ⚡️类适配器适配器的类实现调用接口targetInterface, 并把对适配器的调用委托给它所继承的对象targetClass.????参与者下面列出适配器模式的参与者:targetClass (需要被匹配的类). 类 targetClass 通过接口的方式operationB()对外...阅读全文

博文 2019-08-23 17:33:01 mumushuiding

有关 strings.Builder 内存分配问题?

写到第十一个的时候,就发生了内存分配。为什么会这样? ```go func numAllocs(fn func()) uint64 { defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) var m1, m2 runtime.MemStats runtime.ReadMemStats(&m1) fn() runtime.ReadMemStats(&m2) return m2.Mallocs - m1.Mallocs } func TestStrings_numAllocs(t *testing.T) { // Builder’s inner slice’s capacity: 10 // Builder’s ...阅读全文

图解Go语言内存分配

目录 基础概念 内存管理单元 内存管理组件 mcache mcentral mheap 内存分配流程 总结 参考资料 Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。 Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的TCMalloc算法,全称Thread-Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。 基础概...阅读全文

博文 2019-03-13 10:51:27 qcrao-2018

载:深入 Go 内存分配超级棒的文章:Go 内存分配器可视化指南

载:深入 Go 内存分配超级棒的文章:Go 内存分配器可视化指南本文译者:coldnight译文原链接:https://github.com/coldnight/go-memory-allocator-visual-guide当我第一次开始尝试理解 Go 语言的内存分配器时,整个过程让我抓狂。一切看起来都像一个神秘的黑盒子。因为几乎所有技术魔法(technical wizardry)都隐藏在抽象之下,所以你需要一层一层的剥离才能去理解它。我们将通过这篇文章来一层层的剥离这些细节。如果你想学习所有关于 Go 内存分配器的知识,那么这篇文章正适合你。物理内存和虚拟内存每一个内存分配器都需要运行在由底层操作系统管理的虚拟内存空间(Virtual Memory Space)之上。下图是一个物理内存单...阅读全文

博文 2019-12-23 01:33:03 meng_philip123

[译]Go:内存管理与内存分配

文:medium.com/a-journey-w… 这篇文章是基于Go 1.13的。 当内存不再被使用时,标准库就会自动执行Go内存管理,即从内存分配到Go自己的集合中(from allocation of the memory to its collection)。 虽然开发人员不用去和这些打交道,但是Go的内存管理做了很多优化以及有很多有趣的概念,所以也值得我们去探讨与学习。 堆上的分配 Allocation on the heap 内存管理是在高并发环境以及集成了垃圾回收功能上所设计的。我们来演示一些简单的例子: package main type smallStruct struct { a, b int64 c, d float64 } func main() { smallAll...阅读全文

博文 2019-11-26 18:34:24 野生程序元

[GO语言]Golang String字符串的操作大全

字符串是不可变值类型,内部用指针指向 UTF-8 字节数组。 • 默认值是空字符串 ""。 • 用索引号访问某字节,如 s[i]。 • 不能用序号获取字节元素指针,&s[i] 非法。 • 不可变类型,无法修改字节数组。 • 字节数组尾部不包含 NULL。 使用索引号访问字符 (byte)。 package main func main() { s := "abc" println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63) } 输出结果: true true true 使用 " ` " 定义不做转义处理的原始字符串,支持跨行。 package main func main() { s := `a b\r\n\x00 c` println(s) } 输...阅读全文

博文 2020-05-15 17:38:35 小龙in武汉

golang-接口

Go语言规定,只要实现了接口里面的方法,就是该接口的实现类 接口变量里面有什么? 实现者的类型 和 实现者的指针 接口变量自带指针 接口变量同样采用值传递,几乎不需要使用接口的指针 指针接收者实现只能以指针方式使用;值接收者都可以用 定义一个接口 package main import ( "fmt" "interfaces/mock" "interfaces/real" "time" ) /** Go语言规定,只要实现了接口里面的方法,就是该接口的实现类 接口变量里面有什么? 实现者的类型 和 实现者的指针 接口变量自带指针 接口变量同样采用值传递,几乎不需要使用接口的指针 指针接收者实现只能以指针方式使用;值接收者都可以用 。。。。 type Retriever struct {} ty...阅读全文

博文 2019-12-17 22:32:42 爱吃豆包

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-11-27 18:34:42 Chole121

go 内存管理

内存分配步骤 go 给对象分配内存的主要流程: object size > 32K,则使用 mheap 直接分配。 object size < 16 byte,使用 mcache 的小对象分配器 tiny 直接分配。 (其实 tiny * 就是一个指针,暂且这么说吧。) object size > 16 byte && size <=32K byte 时,先使用 mcache 中对应的 size class 分配。 如果 mcache 对应的 size class 的 span 已经没有可用的块,则向 mcentral 请求。 如果 mcentral 也没有可用的块,则向 mheap 申请,并切分。 如果 mheap 也没有合适的 span,则向操作系统申请。 关键数据结构 mcache 我...阅读全文

博文 2019-12-10 17:33:14 斜不靠谱

golang内存分配

Go语言内置运行时(就是runtime),不同于传统的内存分配方式,go为自主管理,最开始是基于tcmalloc架构,后面逐步迭新。自主管理可实现更好的内存使用模式,如内存池、预分配等,从而避免了系统调用所带来的性能问题。 1. 基本策略 每次从操作系统申请一大块内存,然后将其按特定大小分成小块,构成链表(组织方式是一个单链表数组,数组的每个元素是一个单链表,链表中的每个元素具有相同的大小。); 为对象分配内存时从大小合适的链表提取一小块,避免每次都向操作系统申请内存,减少系统调用。 回收对象内存时将该小块重新归还到原链表,以便复用;若闲置内存过多,则归还部分内存到操作系统,降低整体开销。 1.1 内存块 span:即上面所说的操作系统分配的大块内存,由多个地址连续的页组成; object:...阅读全文

博文 2019-12-28 19:02:49 33debug

Golang 中 new 和 make的区别

参考链接: https://studygolang.com/articles/24026#reply0 Golang 内置两个函数,new 和 make ,其作用都是用来分配内存的。这么说可能会造成混淆,但其实规则很简单,其实他们适用于不同的类型。 make 函数只用于给 slice、map、channel进行初始化; new 函数参数为 一个类型不是一个值,用该类型的零值初始化一块空间,并返回该空间的指针。 我们看一下下面的案例: package main import ( "fmt" ) func main() { var i *int *i=10 fmt.Println(*i) } 运行报错,panic: runtime error: invalid memory address or...阅读全文

博文 2019-10-17 16:33:04 aside section ._1OhGeD

【Golang小知识】new与make的区别

定义 func new(Type) *Type func make(t Type, size ...IntegerType) Type 其中Type代表某一个数据类型。 区别 1.返回值 从定义中可以看出,new返回的是指向Type的指针。make直接返回的是Type类型值。 2.入参 new只有一个Type参数,Type可以是任意类型数据。make可以有多个参数,其中第一个参数与new的参数相同,但是只能是slice,map,或者chan中的一种。对于不同类型,size参数说明如下: 对于slice,第一个size表示长度,第二个size表示容量,且容量不能小于长度。如果省略第二个size,默认容量等于长度。 对于map,会根据size大小分配资源,以足够存储size个元素。如果省略siz...阅读全文

博文 2019-11-17 17:32:41 moonbamboo

内置函数

1. close:主要用来关闭channel 2. len:用来求长度,比如string、array、slice、map、channel 3. new:用来分配内存,主要用来分配值类型,比如int、struct。**返回的是指针** ``` i := 0 j := new(int) *j = 1 ```s1 := new([]int) s2 := make([]int, 10) fmt.Println(s1, " ", s2) 4. make:用来分配内存,主要用来分配引用类型,比如chan、map、slice **make和new的区别:make分配内存空间,返回的是一个值引用;new返回的是一个指针** ``` s1 := new([]int) s2 := make([]int, 10)...阅读全文

博文 2018-10-10 16:09:21 ace_kylin

golang 学习笔记 1.6 字符串

1.6 字符串 字符串是不可变值类型,内部用指针指向 UTF-8 字节数组。 默认值是空字符串 ""。 用索引号访问某字节,如 s[i]。 不能用序号获取字节元素指针,&s[i] 非法。 不可变类型,无法修改字节数组。 字节数组尾部不包含 NULL。 struct String { byte* str; intgo len; }; 使用索引号访问字符 (byte)。 s := "abc" println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63) //输出: true true true 使用 " ` " 定义不做转义处理的原始字符串,支持跨行。 s := `a b\r\n\x00 c` println(s) // 输出: a b\r\n\x00 c...阅读全文

博文 2019-03-22 05:34:40 Diogoxiang

Golang 问题点(一)

1. make和new的区别: make和new都在堆上分配内存. 但是他们的行为不同, 适用于不同的类型. new(T) 返回的是T的指针, 其中T为一个类型, 不是一个值, 为T类型新值分配内存空间并将此空间初始化为T类型的的零值, 返回的是新值得地址,即T的指针*T的值, 该指针指向T的新分配的零值. make(T, args) 用来为slice,map货channel类型分配内存和初始化一个对象, 返回类型的引用we不是指针, 返回值根据T的不同而不同. 简单来讲: new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T) testNew := new([2]int) fmt.Println(testNew) /...阅读全文

博文 2020-02-27 07:32:41 董小贱

简析Go与Java内存管理的差异

前 言 从实践中看,Golang(以下简称Go)应用程序比Java占用更少的内存,这与它们的运行时环境有关,其运行时自带了内存动态分配和自动垃圾回收的管理机制,本文通过分析Go与Java在内存管理机制上的差异,以期对两者在运行时内存方面有更进一步的认识。本文以Go(1.12)和当前使用较多的JDK8 HotSpot VM为例进行说明。本篇文章包含以下内容:介绍Go与Java的运行时内存结构差异介绍Go与Java的内存资源占用差异介绍Go与Java如何为对象分配内存介绍Go与Java的内存回收策略差异 内存结构差异应用程序要能在linux系统上运行(其他平台类似),其可执行文件要求符合ELF规范(Executable and Linkable Format,可执行和可链接格式)。操作系统加载目...阅读全文

博文 2019-06-11 17:32:56 安静的少女

golang 基础(30) WaitGroup

golang_real.jpg golang中有2种方式同步程序,一种使用channel,另一种使用锁机制。sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行。 func main(){ go foo() go bar() } func foo(){ for i := 0; i < 45; i++{ fmt.Println("Foo",i) } } func bar(){ for i := 0; i < 45; i++{ fmt.Println("Bar:",i) } } var wg sync.WaitGroup func...阅读全文

博文 2019-04-03 08:34:38 zidea

3.2.7Golang的指针

总目录:https://www.jianshu.com/p/e406a9bc93a9 Golang - 子目录:https://www.jianshu.com/p/8b3e5b2b4497 指针 和C/C++的指针不同,go语言的指针不能进行偏移与运算,是安全指针。 我们在程序中定义任何量,在内存中都会有属于他的地址,这就是指针。 比如我定义了一个整数20,我在程序中把这个数赋值给变量A,把内存地址赋值给变量B。这时候变量B就是一个指针变量。通过变量A和变量B都能找到这个整数。 Go语言中的指针不能进行偏移和运算,因此Go语言中的指针操作非常简单,我们只需要记住两个符号:&(取地址)和*(根据地址取值) 指针地址 每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。 指针类型 G...阅读全文

博文 2020-03-17 23:32:47 寒暄_HX

兄弟连Go语言培训分享Struct结构体

兄弟连Go语言培训课程体系设计架构包括了区块链的基础语言Go语言、区块链后端技术体系、区块链公链、区块链分布式应用开发等内容讲解,以及到最后的面试指导和项目实战。课程由清华微软谷歌名师团队精心打造,历时半年时间共同研发而出。 先介绍一下go语言的类型系统 Golang中的类型系统 类型系统是指一个语言的类型体系结构。一个典型的类型系统通常包含如下基本内容: q基础类型,如byte、int、bool、float等; q复合类型,如数组、结构体、指针等; q可以指向任意对象的类型(Any类型); q值语义和引用语义; q面向对象,即所有具备面向对象特征(比如成员方法)的类型; q接口。 Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。在需要的时候,你可以给任何类型(包括内置类型)...阅读全文

博文 2018-08-13 17:35:03 兄弟连区块链培训

引用类型介绍

Golang的引用类型包括 slice、map 和 channel。它们有复杂的内部结构,除了申请内存外,还需要初始化相关属性。 内置函数 new 计算类型大小,为其分配零值内存,返回指针。而 make 会被编译器翻译 成具体的创建函数,由其分配内存和初始化成员结构,返回对象而非指针。 package main func main() { a := []int{0, 0, 0} // 提供初始化表达式。 a[1] = 10 b := make([]int, 3) // make slice b[1] = 10 c := new([]int) c[1] = 10 // ./main.go:11:3: invalid operation: c[1] (type *[]int does not s...阅读全文

博文 2019-02-21 01:34:44 weifansym

探索 Go 语言数据类型的内部实现

向新程序员讲解 Go 语言的时候,必要的是解释 Go 各种数据值在内存中的组织来给他们建立正确的思想,知道哪些操作是开销昂贵的,哪些是不昂贵的。这篇文章就是关于基本类型,结构,数组和切片的内部实现原理。基本类型让我们从一个简单的例子开始 图1 变量 i 的类型是 int, 在内存中用一个32比特位的字来表示。j 的类型是 int32 ,由于显示类型转换。即使 i 和 j 由相同的内存布局,他们本质上还是不同的类型:在 Go 中直接 i = j 赋值将会产生一个错误,我们必须显示的转化 j,i = int(j)。值 f 的类型是 float,在内存中用 32 比特位的浮点值格式表示,它和 int32 有相同的内存使用量但是内部布局是不同的,感兴趣的可以去了解一个浮点数如何在内存中表示。结构体和...阅读全文

博文 2020-05-29 13:32:54 CXX_FLAGS

Go内存管理之TCMalloc

自公众号:灰子学技术,原文链接:https://mp.weixin.qq.com/s/-b26YiHjL3V9CNvk0LZmEgTCMalloc作为Go语言内存管理的核心算法,是理解和掌握Go的内存管理非常重要的一步,本章主要介绍TCMalloc的是什么样子的。TCMalloc的概述 TCMalloc全称是Thread-Caching Malloc,是Google 开发的内存分配器,在不少项目中都有使用,例如在 Golang 中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征:对抗内存碎片、在多核处理器能够 scale。1. TCMalloc相比glibc 2.3而言内存分配更快。2.TCMalloc对于多线程程序而言,减少了锁机制,对于小对象而言,可以说没有锁的操作,对于...阅读全文

博文 2020-01-27 17:32:46 灰常出色

Golang new和 make的区别

Go提供了两种分配原语,即new和make。它们所做的事情是不一样的,所应用的类型也不同。new用来分配内存,但与其他语言中的同名函数不同,它不会初始化内存,只会讲内存置零;也就是说,new(T)会为类型为T的新项分配已置零的内存空间,并返回他的地址,也就是一个类型为*T的值。用Go的术语来说,它返回一个指针,改指针指向新分配的,类型为T的零值;make的目的不同于new,它只用于slice,map,channel的创建,并返回类型为T(非指针)的已初始化(非零值)的值;出现这种差异的原因在于,这三种类型本质上为引用类型,它们在使用前必须初始化;小结:new和make都在堆上分配内存,但是它们的行为不同,适用于不同的类型。new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型...阅读全文

博文 2020-05-12 19:32:47 算法设计与分析

golang并发编程-20190624

进程 进程是操作系统进行资源分配的一个基本单元,由于描述程序执行的过程。 所有的进程都有父进程,所有的进程共同组成了一个树状结构 内核启动进程是所有进程的祖先,他自己作为自己的父进程 进程标识 内核对每个进程的属性和行为进行详细记录 pid就是这个唯一标识,pid为1的就是上面说的内核启动进程 image.png ppid就是当前进程的父进程 pid := os.Getpid() ppid := os.Getppid() 通过以上方法可以获取到对应的pid和ppid 进程空间 一个用户进程总会生存与用户的空间中 image.pn...阅读全文

图解Go语言内存分配

Go语言内置运行时(就是runtime),抛弃了传统的内存分配方式,改为自主管理。这样可以自主地实现更好的内存使用模式,比如内存池、预分配等等。这样,不会每次内存分配都需要进行系统调用。Golang运行时的内存分配算法主要源自 Google 为 C 语言开发的 TCMalloc算法,全称 Thread-CachingMalloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。为了更好的阅读体验,手动贴上文章目录: 基础概念Go在程序启动的时候,会先向操作系统申请一块内存(注意这时还只是一段虚拟的地址...阅读全文

博文 2019-03-14 01:34:40 ddu_sw

探索 Go 语言数据类型的内部实现

向新程序员讲解 Go 语言的时候,必要的是解释 Go 各种数据值在内存中的组织来给他们建立正确的思想,知道哪些操作是开销昂贵的,哪些是不昂贵的。这篇文章就是关于基本类型,结构,数组和切片的内部实现原理。基本类型让我们从一个简单的例子开始​图1 变量 i 的类型是 int, 在内存中用一个32比特位的字来表示。j 的类型是 int32 ,由于显示类型转换。即使 i 和 j 由相同的内存布局,他们本质上还是不同的类型:在 Go 中直接 i = j 赋值将会产生一个错误,我们必须显示的转化 j,i = int(j)。 值 f 的类型是 float,在内存中用 32 比特位的浮点值格式表示,它和 int32 有相同的内存使用量但是内部布局是不同的,感兴趣的可以去了解一个浮点数如何在内存中表示。结构体...阅读全文

Golang之变量去哪儿?

写过C/C++的同学都知道,调用著名的malloc和new函数可以在堆上分配一块内存,这块内存的使用和销毁的责任都在程序员。一不小心,就会发生内存泄露,搞得胆战心惊。切换到Golang后,基本不会担心内存泄露了。虽然也有new函数,但是使用new函数得到的内存不一定就在堆上。堆和栈的区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成的。一个变量是在堆上分配,还是在栈上分配,是经过编译器的逃逸分析之后得出的结论。这篇文章,就将带领大家一起去探索逃逸分析——变量到底去哪儿,堆还是栈?什么是逃逸分析以前写C/C++代码时,为了提高效率,常常将pass-by-value(传值)“升级”成pass-by-reference,企图避免构造函数的运行,并且直接返回一个指针。你一定还记得,这...阅读全文

博文 2019-03-02 12:07:25 饶全成