目录导航
-
撤销(Ctrl+Z)
-
重做(Ctrl+Y)
-
清空
-
H
标题(Ctrl+1~6)
- 一级标题
- 二级标题
- 三级标题
- 四级标题
- 五级标题
- 六级标题
-
粗体(Ctrl+B)
-
斜体(Ctrl+I)
-
删除线
-
插入引用(Ctrl+Q)
-
无序列表(Ctrl+U)
-
有序列表(Ctrl+O)
-
表格
-
插入分割线
-
插入链接(Ctrl+L)
-
插入图片
- 添加图片链接
-
插入代码块
-
保存(Ctrl+S)
-
开启预览
-
开启目录导航
-
关闭同步滚动
-
全屏(按ESC还原)
## Go中new和make的区别 #### 在Go中,的值类型和引用类型: * 值类型:int,float,bool,string,struct和array. 变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。 * 引用类型:slice,map,chan,接口interface,函数,和值类型对应的指针. 变量存储的是一个地址(或者理解为指针),指针指向内存中真正存储数据的首地址。内存通常在堆上分配,通过GC回收。 这里需要注意的是: 对于引用类型的变量,我们不仅要声明变量,更重要的是,我们得手动为它分配空间. * 因此new该方法的参数要求传入一个类型,而不是一个值,它会申请一个该类型大小的内存空间,并会初始化为对应的零值,返回指向该内存空间的一个指针。 ``` // The new built-in function allocates memory. The first argument is a type, // not a value, and the value returned is a pointer to a newly // allocated zero value of that type. func new(Type) *Type ``` * 而make也是用于内存分配,但是和new不同,只用来引用对象slice、map和channel的内存创建,它返回的类型就是类型本身,而不是它们的指针类型。 ``` // The make built-in function allocates and initializes an object of type // slice, map, or chan (only). Like new, the first argument is a type, not a // value. Unlike new, make's return type is the same as the type of its // argument, not a pointer to it. The specification of the result depends on // the type: // Slice: The size specifies the length. The capacity of the slice is // equal to its length. A second integer argument may be provided to // specify a different capacity; it must be no smaller than the // length. For example, make([]int, 0, 10) allocates an underlying array // of size 10 and returns a slice of length 0 and capacity 10 that is // backed by this underlying array. // Map: An empty map is allocated with enough space to hold the // specified number of elements. The size may be omitted, in which case // a small starting size is allocated. // Channel: The channel's buffer is initialized with the specified // buffer capacity. If zero, or the size is omitted, the channel is // unbuffered. func make(t Type, size ...IntegerType) Type ``` ## 栈的内存是怎么分配的 栈和堆只是虚拟内存上2块不同功能的内存区域: * 栈在高地址,从高地址向低地址增长。 * 堆在低地址,从低地址向高地址增长。 栈和堆相比优势: * 栈的内存管理简单,分配比堆上快。 * 栈的内存不需要回收,而堆需要,无论是主动free,还是被动的垃圾回收,这都需要花费额外的CPU。 * 栈上的内存有更好的局部性,堆上内存访问就不那么友好了,CPU访问的2块数据可能在不同的页上,CPU访问数据的时间可能就上去了。 堆栈缓存方式: * 栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。 堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。 ## 堆的内存是怎么分配的 * 堆内存管理中主要是三部分, 1.分配内存块,2.回收内存块, 3.组织内存块。 一个内存块包含了3类信息,如下图所示,元数据、用户数据和对齐字段,内存对齐是为了提高访问效率。下图申请5Byte内存的时候,就需要进行内存对齐。 ![image.png](https://wenknow-img.oss-cn-shanghai.aliyuncs.com/img/article/2022-02-11/1644548235-image.png) * 释放内存实质是把使用的内存块从链表中取出来,然后标记为未使用,当分配内存块的时候,可以从未使用内存块中有先查找大小相近的内存块,如果找不到,再从未分配的内存中分配内存。 上面这个简单的设计中还没考虑内存碎片的问题,因为随着内存不断的申请和释放,内存上会存在大量的碎片,降低内存的使用率。为了解决内存碎片,可以将2个连续的未使用的内存块合并,减少碎片。
Go中new和make的区别
在Go中,的值类型和引用类型:
-
值类型:int,float,bool,string,struct和array.
变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。 -
引用类型:slice,map,chan,接口interface,函数,和值类型对应的指针.
变量存储的是一个地址(或者理解为指针),指针指向内存中真正存储数据的首地址。内存通常在堆上分配,通过GC回收。
这里需要注意的是: 对于引用类型的变量,我们不仅要声明变量,更重要的是,我们得手动为它分配空间. -
因此new该方法的参数要求传入一个类型,而不是一个值,它会申请一个该类型大小的内存空间,并会初始化为对应的零值,返回指向该内存空间的一个指针。
// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type
- 而make也是用于内存分配,但是和new不同,只用来引用对象slice、map和channel的内存创建,它返回的类型就是类型本身,而不是它们的指针类型。
// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
// Slice: The size specifies the length. The capacity of the slice is
// equal to its length. A second integer argument may be provided to
// specify a different capacity; it must be no smaller than the
// length. For example, make([]int, 0, 10) allocates an underlying array
// of size 10 and returns a slice of length 0 and capacity 10 that is
// backed by this underlying array.
// Map: An empty map is allocated with enough space to hold the
// specified number of elements. The size may be omitted, in which case
// a small starting size is allocated.
// Channel: The channel's buffer is initialized with the specified
// buffer capacity. If zero, or the size is omitted, the channel is
// unbuffered.
func make(t Type, size ...IntegerType) Type
栈的内存是怎么分配的
栈和堆只是虚拟内存上2块不同功能的内存区域:
- 栈在高地址,从高地址向低地址增长。
- 堆在低地址,从低地址向高地址增长。
栈和堆相比优势:
- 栈的内存管理简单,分配比堆上快。
- 栈的内存不需要回收,而堆需要,无论是主动free,还是被动的垃圾回收,这都需要花费额外的CPU。
- 栈上的内存有更好的局部性,堆上内存访问就不那么友好了,CPU访问的2块数据可能在不同的页上,CPU访问数据的时间可能就上去了。
堆栈缓存方式:
- 栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。
堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
堆的内存是怎么分配的
-
堆内存管理中主要是三部分, 1.分配内存块,2.回收内存块, 3.组织内存块。
一个内存块包含了3类信息,如下图所示,元数据、用户数据和对齐字段,内存对齐是为了提高访问效率。下图申请5Byte内存的时候,就需要进行内存对齐。
-
释放内存实质是把使用的内存块从链表中取出来,然后标记为未使用,当分配内存块的时候,可以从未使用内存块中有先查找大小相近的内存块,如果找不到,再从未分配的内存中分配内存。
上面这个简单的设计中还没考虑内存碎片的问题,因为随着内存不断的申请和释放,内存上会存在大量的碎片,降低内存的使用率。为了解决内存碎片,可以将2个连续的未使用的内存块合并,减少碎片。
评论
请
登录后发表观点