- <content type="html"><![CDATA[<p>为了缓解GC压力,go标准库在sync包中提供了一个Pool,但是这个Pool和我们一般意义上的Pool不太一样,主要有以下几点区别:<br>1.Pool无法设置大小,所以理论上只受限于系统内存大小。<br>2.Pool中的对象不支持自定义过期时间及策略,究其原因,Pool并不是一个Cache.<br>3.Pool的设计初衷是为了缓解GC压力,所以Pool中的对象会在GC开始前全部清除。</p><a id="more"></a><p>下面这段注释来源于<code>pool.go</code>:<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// A Pool is a set of temporary objects that may be individually saved and</span></span><br><span class="line"><span class="comment">// retrieved.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Any item stored in the Pool may be removed automatically at any time without</span></span><br><span class="line"><span class="comment">// notification. If the Pool holds the only reference when this happens, the</span></span><br><span class="line"><span class="comment">// item might be deallocated.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// A Pool is safe for use by multiple goroutines simultaneously.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// Pool's purpose is to cache allocated but unused items for later reuse,</span></span><br><span class="line"><span class="comment">// relieving pressure on the garbage collector. That is, it makes it easy to</span></span><br><span class="line"><span class="comment">// build efficient, thread-safe free lists. However, it is not suitable for all</span></span><br><span class="line"><span class="comment">// free lists.</span></span><br></pre></td></tr></table></figure></p><p>让我们用代码验证一下 sync.Pool中对象的回收时机:<br><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"runtime"</span></span><br><span class="line"><span class="string">"sync"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line"></span><br><span class="line">p := &sync.Pool{</span><br><span class="line">New: <span class="function"><span class="keyword">func</span><span class="params">()</span> <span class="title">interface</span></span>{} {</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">},</span><br><span class="line">}</span><br><span class="line">a := p.Get().(<span class="keyword">int</span>)</span><br><span class="line">p.Put(<span class="number">1</span>)</span><br><span class="line">b := p.Get().(<span class="keyword">int</span>)</span><br><span class="line">fmt.Println(a, b)</span><br><span class="line"></span><br><span class="line">a = p.Get().(<span class="keyword">int</span>)</span><br><span class="line">p.Put(<span class="number">1</span>)</span><br><span class="line">runtime.GC() <span class="comment">//手动调用GC</span></span><br><span class="line">b = p.Get().(<span class="keyword">int</span>)</span><br><span class="line">fmt.Println(a, b)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>执行结果分别打印出了:</p><pre><code>0 10 0</code></pre><p>可见,在手动调用GC之后,Pool中的对象被全部清除了,在Get的时候重新调用定义的New方法创建了新的对象</p>]]></content>
0 commit comments