goroutine内开buf导致内存耗尽

realted · 2017-09-18 08:31:27 · 1738 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-09-18 08:31:27 的主题,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
)

func main() {
    for {
        go NewJob()
    }
}

func NewJob() {
    var buf [1024]byte
    fmt.Println(buf)
}

内存持续上涨,到一定程度直接因为内存读取过多闪退崩溃。如果真的遇到这种情况的程序,需要goroutine里开很多buf,该这么解决?

请问何解


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1738 次点击  
加入收藏 微博
7 回复  |  直到 2017-09-21 15:55:22
channel
channel · #1 · 8年之前

你这样无休止,死循环的开,肯定耗尽。实际程序如果真这么大的量,一方面考虑重用,比如对象池;另一方面,可能需要更多机器了。

realted
realted · #2 · 8年之前

@channel 哪些开源项目使用了“重用对象池”的方法?请赐教,我去学习一下

realted
realted · #3 · 8年之前

即使一秒只开一个buf,也很容易耗尽啊。为什么goroutine结束不去自动释放资源呢?想不通啊

qiangmzsx
qiangmzsx · #4 · 8年之前
realtedrealted #2 回复

@channel 哪些开源项目使用了“重用对象池”的方法?请赐教,我去学习一下

sync.pool

realted
realted · #5 · 8年之前
jingniao
jingniao · #6 · 8年之前
realtedrealted #3 回复

即使一秒只开一个buf,也很容易耗尽啊。为什么goroutine结束不去自动释放资源呢?想不通啊

你所说的1秒钟开一个buf,容易耗尽?我在你的程序的for循环里sleep 1秒后,基本上内存维持在2M以内并且没有看到增长啊
这样疯狂的开goroutine,我实验到2钟崩溃的情况 1:因为短时间巨量的终端输出,导致拿不到相关锁 panic了 2:单个goroutine中分配过多的内存,同一时间又很多goroutine,导致在go的垃圾回收之前耗尽内存,我这边环境是大致每个goroutine分配高于10M的内存的时候会出现这种情况,如果低于10M,则内存会维持在一个稳定的数值,如果在for语句中添加间隔输出(每开1000个goroutine输出一次)会明显感觉到程序的停顿,应该就是gc在运行了

sevenhe
sevenhe · #7 · 8年之前

gc有自己的触发机制,可以google一下,但是通用的想法是: 不要依赖这个机制释放内存,只当作一个锦上添花的东西,要保证自己的程序稳定运行,要评估一下并发量,限制goroutine的数量。 比如一个goroutine占用2M内存,(2M我觉的不少了,啥都可以算上了),那么4g可用内存的机器,不考虑goroutine调度的情况下,可以支持2000并发数,2000并发每秒的单机我觉得已经是相当不错的业务了,毕竟一般都不可能是单台机器组成服务。

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传