Go 1.3 的sync包中加入一个新特性:Pool。官方文档可以看这里http://golang.org/pkg/sync/#Pool

这个类设计的目的是用来保存和复用临时对象,以减少内存分配,降低CG压力。

type Pool
func (p *Pool) Get() interface{}
func (p *Pool) Put(x interface{})
New func() interface{}

下面说说Pool的实现:

1.定时清理

文档上说,保存在Pool中的对象会在没有任何通知的情况下被自动移除掉。实际上,这个清理过程是在每次垃圾回收之前做的。垃圾回收是固定两分钟触发一次。而且每次清理会将Pool中的所有对象都清理掉!

2.如何管理数据

先看看两个数据结构

type Pool struct {
local unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
localSize uintptr // size of the local array // New optionally specifies a function to generate
// a value when Get would otherwise return nil.
// It may not be changed concurrently with calls to Get.
New func() interface{}
} // Local per-P Pool appendix.
type poolLocal struct {
private interface{} // Can be used only by the respective P.
shared []interface{} // Can be used by any P.
Mutex // Protects shared.
pad [128]byte // Prevents false sharing.
}

  

Pool是提供给外部使用的对象。其中的local成员的真实类型是一个poolLocal数组,localSize是数组长度。poolLocal是真正保存数据的地方。priveate保存了一个临时对象,shared是保存临时对象的数组。

为什么Pool中需要这么多poolLocal对象呢?实际上,Pool是给每个线程分配了一个poolLocal对象。也就是说local数组的长度,就是工作线程的数量(size := runtime.GOMAXPROCS(0))。当多线程在并发读写的时候,通常情况下都是在自己线程的poolLocal中存取数据。当自己线程的poolLocal中没有数据时,才会尝试加锁去其他线程的poolLocal中“偷”数据。

func (p *Pool) Get() interface{} {
if raceenabled {
if p.New != nil {
return p.New()
}
return nil
}
l := p.pin() // 获取当前线程的poolLocal对象,也就是p.local[pid]。
x := l.private
l.private = nil
runtime_procUnpin()
if x != nil {
return x
}
l.Lock()
last := len(l.shared) - 1
if last >= 0 {
x = l.shared[last]
l.shared = l.shared[:last]
}
l.Unlock()
if x != nil {
return x
}
return p.getSlow()
}

Pool.Get的时候,首先会在local数组中获取当前线程对应的poolLocal对象。如果private中有数据,则取出来直接返回。如果没有则先锁住shared,有数据则直接返回。

为什么这里要锁住。答案在getSlow中。因为当shared中没有数据的时候,会尝试去其他的poolLocal的shared中偷数据。

Go语言的goroutine虽然可以创建很多,但是真正能物理上并发运行的goroutine数量是有限的,是由runtime.GOMAXPROCS(0)设置的。所以这个Pool高效的设计的地方就在于将数据分散在了各个真正并发的线程中,每个线程优先从自己的poolLocal中获取数据,很大程度上降低了锁竞争。  

  

Golang 临时对象池 sync.Pool的更多相关文章

  1. go语言学习--go的临时对象池--sync.Pool

    一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用于存储那些被分配了但是没有被使用,而未来可能会使用的值,以减小垃圾回收的压力.一个比较好的例子是fmt包,fmt包总 ...

  2. go的临时对象池--sync.Pool

    作者:bigtom链接:https://www.jianshu.com/p/2bd41a8f2254來源:简书   一个sync.Pool对象就是一组临时对象的集合.Pool是协程安全的. Pool用 ...

  3. [译]Unity3D内存管理——对象池(Object Pool)

    原文地址:C# Memory Management for Unity Developers (part 3 of 3), 其实从原文标题可以看出,这是一系列文章中的第三篇,前两篇讲解了从C#语言本身 ...

  4. 对象池 object pool

    对象池适用于: 对象的创建很耗时 对象频繁地释放再创建 对象池的实现:将释放的对象放进对象池中,在新建对象时,从对象池取对象 public class ObjectPool<T> wher ...

  5. 深度解密 Go 语言之 sync.Pool

    最近在工作中碰到了 GC 的问题:项目中大量重复地创建许多对象,造成 GC 的工作量巨大,CPU 频繁掉底.准备使用 sync.Pool 来缓存对象,减轻 GC 的消耗.为了用起来更顺畅,我特地研究了 ...

  6. golang sync.Pool包的使用和一些注意地方

    package main; import ( "sync" "fmt" "net" "runtime" ) //sync ...

  7. 深入Golang之sync.Pool详解

    我们通常用golang来构建高并发场景下的应用,但是由于golang内建的GC机制会影响应用的性能,为了减少GC,golang提供了对象重用的机制,也就是sync.Pool对象池. sync.Pool ...

  8. golang协程池设计

    Why Pool go自从出生就身带“高并发”的标签,其并发编程就是由groutine实现的,因其消耗资源低,性能高效,开发成本低的特性而被广泛应用到各种场景,例如服务端开发中使用的HTTP服务,在g ...

  9. Unity对象池的实现

    对象池是一个单例类: using System.Collections; using System.Collections.Generic; using UnityEngine; public cla ...

随机推荐

  1. Java基础教程(18)--继承

    一.继承的概念   继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...

  2. java类中成员的初始化顺序(一)

    类被创建之后的成员的初始化顺序到底是怎么样的? 首先 不考虑继承 package com; public class DemoOne { /** * 关于类的初始化顺序 */ //不考虑继承结构的情况 ...

  3. 关于pycharm 打不开某些文件夹和文件打不开的问题

    在使用pycharm的时候遇到了一个情况, 下载了一个文件,自己修改了文件夹名称后再打开文件夹里的py文件, 打不开了,pycharm没有反应, 百度了一下,没有类似的问题,觉得应该是个个例... 然 ...

  4. js-权威指南学习笔记15

    第十五章 脚本化文档 1.文档对象模型DOM是表示和操作HTML和XML文档内容的基础API. 2.Document.Element.Text是Node的子类. 3.查询文档的一个或多个元素有如下方法 ...

  5. iPhone中调用WCF服务

    本文介绍的是跨平台iPhone中调用WCF服务,WCF是由微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,由 .NET Framework 3.0+开始引入 iPhone中调用WC ...

  6. android studio使用openssl

    前言 逆向的基础是开发, 逆向分析时很多时候会使用一些公开的加密函数来对数据进行加密,通过使用 openssl 熟悉下. 正文 首先得先编译出来 openssl,然后把它们复制到你的工程目录下. in ...

  7. linux yum 安装wget、gcc、ifconfig、vim、setup

    安装wgetyum -y install wget安装gcc c语言编译器yum -y install gcc安装ifconfigyum -y install net-tools.x86_64安装vi ...

  8. 2java.lang.NoClassDefFoundError异常

    1.错误信息 2.错误分析: JVM读到程序的第三行,会在当前路径 "D:\java" 下寻找com.yangquan.aolun这个包路径下的Cat类,但当前路径下根本就没有co ...

  9. CSS 小结笔记之背景

    背景相关属性主要有: background-color  背景颜色 background-image 背景图片 background-repeat 是否平铺 repeat (默认平铺) | repea ...

  10. Python 执行主程序

    主程序里的代码包含的东西比较多, 如果在程序的.py文件里执行还要再调一遍方法, 但通常这个调用在测试完结后是要删掉的. 那么问题来了, 如果把这个代码直接发给别人, 执行时要再加上调用, 这个就很烦 ...