Go 语言从入门到实战
蔡超
Mobvista 技术副总裁兼首席架构师,前亚马逊(中国)首席软件架构师
48919 人已学习
新⼈⾸单¥59
课程目录
已完结/共 55 讲
第一章:Go语言简介 (4讲)
第二章:基本程序结构 (4讲)
第三章:常用集合 (3讲)
第四章:字符串 (1讲)
时长 16:47
第五章:函数 (2讲)
第六章:面向对象编程 (4讲)
第七章:编写好的错误处理 (2讲)
第八章:包和依赖管理 (2讲)
第九章:并发编程 (7讲)
第十章:典型并发任务 (5讲)
第十一章:测试 (3讲)
时长 11:48
时长 07:12
时长 06:15
第十二章:反射和Unsafe (3讲)
时长 08:18
时长 08:03
第十三章:常见架构模式的实现 (2讲)
第十四章:常见任务 (4讲)
时长 04:27
时长 05:14
第十五章:性能调优 (4讲)
第十六章:高可用性服务设计 (5讲)
Go 语言从入门到实战
登录|注册
留言
17
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 34 | sync.pool对象缓存
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | Go语言课程介绍
02 | 内容综述
03 | Go语言简介:历史背景、发展现状及语言特性
04 | 编写第一个Go程序
05 | 变量、常量以及与其他语言的差异
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言中实现Set
12 | 字符串
13 | Go语言的函数
14 | 可变参数和defer
15 | 行为的定义和实现
16 | Go语言的相关接口
17 | 扩展与复用
18 | 不一样的接口类型,一样的多态
19 | 编写好的错误处理
20 | panic和recover
21 | 构建可复用的模块(包)
22 | 依赖管理
23 | 协程机制
24 | 共享内存并发机制
25 | CSP并发机制
26 | 多路选择和超时
27 | channel的关闭和广播
28 | 任务的取消
29 | Context与任务取消
30 | 只运行一次
31 | 仅需任意任务完成
32 | 所有任务完成
33 | 对象池
34 | sync.pool对象缓存
35 | 单元测试
36 | Benchmark
37 | BDD
38 | 反射编程
39 | 万能程序
40 | 不安全编程
41 | 实现pipe-filter framework
42 | 实现micro-kernel framework
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结课测试&结束语
登录 后留言

全部留言(17)

  • 最新
  • 精选
thomas
为什么加上runtime.GC()这句后,依然还是会读取缓存? func main() { pool := &sync.Pool{ New: func() interface{}{ fmt.Println("create a new object") return 100 }, } v,ok := pool.Get().(int) fmt.Println(v,ok) pool.Put(3) runtime.GC() v,ok = pool.Get().(int) fmt.Println(v,ok) } 运行结果: create a new object 100 true 3 true

作者回复: 你使用的是那个版本呢? 官方Go runtime 1.13将对sync.Pool中的对象回收时机策略做出调整。在1.12版本及以前的版本中,在每轮垃圾回收过程中,每个sync.Pool实例中的所有缓存对象都将被无条件回收掉。从1.13版本开始,如果一个sync.Pool实例在上一轮垃圾回收过程结束之后仍然被使用过,则其中的缓存对象将不会被回收掉。此举对于使用sync.Pool来提升效率的程序来说,将大大减少周期性的因为缓存被清除而造成的瞬时效率下降。

2019-11-20
7
9
james
老师, put 的顺序, 和 get 出来的顺序为啥不一样呢, 这个是queue还是stack 呢, 貌似都不是 pool := sync.Pool{New: func() interface{} { return 10 }} pool.Put(1) pool.Put(2) pool.Put(3) t.Log(pool.Get().(int)) // 1 t.Log(pool.Get().(int)) // 3 t.Log(pool.Get().(int)) // 2

作者回复: 第一个 Get取出的是私有池中的,私有池仅可放一个对象 后面的Get取出的则是共享池中的,而共享池的是后进先出的。可以参考sync.pool的源代码: func (p *Pool) Get() interface{} { if race.Enabled { race.Disable() } l := p.pin() x := l.private l.private = nil runtime_procUnpin() if x == nil { l.Lock() last := len(l.shared) - 1 if last >= 0 { x = l.shared[last] l.shared = l.shared[:last] }

2020-03-11
6
manatee
请教一下老师在初始化sync.pool中那个New:func() 是什么写法呢,之前好像没遇到过

作者回复: 这个就是在函数课程中提到,方法在Go中方法是第一公民,所以New是结构体中一个变量,而这个变量的值是个方法。这里你把自定义的方法作为变量值付给了New

2019-04-03
6
escray
sync.pool 对象缓存,而不是对象池,不适合于做连接池 私有对象,而不是私有对象池 私有对象访问的时候(写入)不需要锁;共享池写入需要锁 如果使用 sync.pool 来缓存对象,那么每次访问的时候都有可能会遇到锁的问题,锁的开销和创建对象的开销需要进行比较和权衡,才能决定应该使用哪种方式。 go 1.13 版本后,对于 sync.pool 中缓存的对象,会被放入 victim 中,此时还可以被访问到,直到第二次 GC 我觉的这门课程应该是老师和同学们共创,如果不看留言的话(包括作者回复部分),那么会缺失不少内容。

作者回复: 没错。其实每一节课都应该这样

2021-04-10
2
Calvin
老师,最后的例子中,Put 进去 3 个 100,我这里测试有时会只输出 2 个 100,有时又是 3 个,这是不是因为“协程安全”问题,Put、Get 2 个操作非原子性的原因?但是例子中 3 个 Put 是在所有 Get 前面的,难道 Put 它不是同步的吗? 我用的 Go 版本是 1.16.5。

作者回复: 官方Go runtime 1.13后对sync.Pool中的对象回收时机策略做出调整。在1.12版本及以前的版本中,在每轮垃圾回收过程中,每个sync.Pool实例中的所有缓存对象都将被无条件回收掉。从1.13版本开始,如果一个sync.Pool实例在上一轮垃圾回收过程结束之后仍然被使用过,则其中的缓存对象将不会被回收掉。此举对于使用sync.Pool来提升效率的程序来说,将大大减少周期性的因为缓存被清除而造成的瞬时效率下降。

2021-06-27
1
八宝
go v1.16 版 测试GC对 sync.Pool的影响 1). Get 1次,Put 1次,GC,Get1次 v := pool.Get().(int) fmt.Println(v) pool.Put(3) runtime.GC() v1, _ := pool.Get().(int) fmt.Println(v1) 反复执行多次后,出现以下两种打印 (i) create a new object. 100 create a new object. 100 可能的原因: GC 时把Pool 清掉了?? 难道触发了2次GC吗 (ii) create a new object. 100 3 可能的原因:GC时候没有清掉Pool ? 这种问题如何排查,老师能给点思路吗?

作者回复: 我认为这个是由于在Go1.13版本后引入了victim cache机制的原因,每一次GC并不一定会销毁所有缓存对象。这样的好处是: 1. 减少回收对象的数量,缩短GC时间 2. 提高缓存的命中率

2021-03-05
魏颖琪
在go doc中这样描述:A Pool is safe for use by multiple goroutines simultaneously. 并没有提及共享池的协程不安全。请问老师,如何理解pool是否协程安全?

作者回复: 其实在我的总结里提到了,sync.Pool是可以在多协程的情况下使用的,但是在访问共享池时,会有锁的开销。 -协程安全,会有锁的开销

2019-08-08
tjudream
老师能否讲解一些Go语言的内存模型,以及Go语言的垃圾回收机制。 Go语言和也向Java一样分为堆内存、栈内存和永久区吗? Go语言是使用协程去做垃圾回收的吗?是否和Java一样存在Stop The World的情况? Go语言没有像Java一样的JVM虚拟机,那它是编译的时候把垃圾回收、协程管理等相关的代码都编译进去了吗?每个Go的二进制包中都存在这些指令吗?
2019-04-04
14
忽然之间
视频内容点到为止,每次听了还要去搜索各种资源来加深理解,希望老师给提供一些更恰当的、提供思考方向、更具实战的例子。
2019-04-19
13
Terence孫
这里sync.Pool的生命周期需要说明下 Go 1.13版本以前,里面缓存的生命周期是下次GC之前 GO 1.13版本以后,里面缓存的生命周期是下下次GC之前,在第一次执行GC时会将对象放入victim中,在此的数据还是可以获取得到,当GC再此执行时victim中旧数据将被新淘汰得数据替换,此时数据彻底删除
2020-09-17
8
收起评论