由浅入深聊聊Golang的sync.Pool

2024-06-20 20:38

本文主要是介绍由浅入深聊聊Golang的sync.Pool,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

今天在思考优化GC的套路,看到了sync.Pool,那就来总结下,希望可以有个了断。

用最通俗的话,讲明白知识。以下知识点10s后即将到来。

1.pool是什么?
2.为什么需要sync.Pool?
3.如何使用sync.Pool?
4.走一波源码
5.源码关键点解析

正文

1.sync.Pool是什么?

Golang在 1.3 版本的时候,在sync包中加入一个新特性:Pool。
简单的说:就是一个临时对象池

2.为什么需要sync.Pool?

保存和复用临时对象,减少内存分配,降低GC压力。

(对象越多GC越慢,因为Golang进行三色标记回收的时候,要标记的也越多,自然就慢了)

3.如何使用sync.Pool?

func main() {// 初始化一个poolpool := &sync.Pool{// 默认的返回值设置,不写这个参数,默认是nilNew: func() interface{} {return 0},}// 看一下初始的值,这里是返回0,如果不设置New函数,默认返回nilinit := pool.Get()fmt.Println(init)// 设置一个参数1pool.Put(1)// 获取查看结果num := pool.Get()fmt.Println(num)// 再次获取,会发现,已经是空的了,只能返回默认的值。num = pool.Get()fmt.Println(num)
}

使用较为简单。
总的思路就是:搞一个池子,预先放入临时产生的对象,然后取出使用

可能有同学问了,这个玩意儿官方出的,那他自己有在用吗?
答案是有的,其实你也一直在用。

就是fmt包啦,由于fmt总是需要很多[]byte对象,索性就直接建了一个[]byte对象的池子,来走一波代码。

type buffer []byte
// printer状态的结构体()
type pp struct {...
}// pp的对象池, 《====这里用到了。
var ppFree = sync.Pool{New: func() interface{} { return new(pp) },
}// 每次需要pp结构体的时候,都过sync.Pool进行获取。
func newPrinter() *pp {p := ppFree.Get().(*pp)p.panicking = falsep.erroring = falsep.fmt.init(&p.buf)return p
}

4.走一波源码

4.1 基础数据结构

type Pool struct {// noCopy,防止当前类型被copy,是一个有意思的字段,后文详说。noCopy noCopy// [P]poolLocal 数组指针local     unsafe.Pointer// 数组大小localSize uintptr        // 选填的自定义函数,缓冲池无数据的时候会调用,不设置默认返回nilNew func() 

这篇关于由浅入深聊聊Golang的sync.Pool的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079203

相关文章

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

golang版本升级如何实现

《golang版本升级如何实现》:本文主要介绍golang版本升级如何实现问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录golanwww.chinasem.cng版本升级linux上golang版本升级删除golang旧版本安装golang最新版本总结gola

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time