一个goroutine要消耗多少内存呢以及一个简单的测试

290 views
Skip to first unread message

damacheng009

unread,
Sep 29, 2012, 6:00:54 AM9/29/12
to golang-china
做了个小测试,代码如下:
 
package main
import (
        "fmt"
        "os"
        "strconv"
        "time"
)
func calc(c chan int) {
        result := 0
        for i := 0; i < 10000; i++ {
                result += i
        }
        c <- result
}
func main() {
        prev := time.Now()
        count, _ := strconv.Atoi(os.Args[1])
        c := make(chan int, count)
        for i := 0; i < count; i++ {
                go calc(c)
        }
        for i := 0; i < count; i++ {
                <- c
        }
        now := time.Now()
        fmt.Println(now.Sub(prev))
}
 
命令行传的是1000000,跑起来瞬间占了4G内存,传2000000的话,8G的内存就不够使了,就频繁的换进换出了,
让我奇怪的事,一个goroutine运行完后,占用的内存应该被回收吧,可貌似看不到效果。
内存是耗得大,但计算速度快得多了。
用JAVA的线程做同样的测试就慢得多,但内存耗得没那么恐怖。
 
有兴趣大家可以讨论下,谢谢~
 
 
 
 
2012-09-29

damacheng009

发件人: damacheng009
发送时间: 2012-09-29  16:12:20
收件人: golang-china
抄送:
主题: 关于golang的HTTP模块的性能测试
大家好:
我使用golang的net/http包建了一个HTTP接口,用AB工具做压力测试,发现并发怎么设,每秒请求数量都上不去,CPU的核数我也设置了,CPU总在120左右。
在此期间进程的goroutine数都不过超过10,请问大家有啥优化方法吗,还是自带的包的性能就是这样了,谢谢大家。
 
 
 
2012-09-29

damacheng009

Ruiqi Hong

unread,
Sep 29, 2012, 6:25:49 AM9/29/12
to golang...@googlegroups.com

   for i := 0; i < count; i++ {
                go calc(c)
        }
这个循环结束之前没有goroutine退出啊
2012/9/29 damacheng009 <damach...@gmail.com>

--
官网: http://golang-china.org/
IRC: irc.freenode.net #golang-china
@golangchina

damacheng009

unread,
Sep 29, 2012, 6:31:06 AM9/29/12
to golang-china
不会吧。。我makde的channel是带缓冲的呀,一个goroutine向里面塞数据后不会阻塞住就马上返回了呀。。请赐教..
 
 
2012-09-29

damacheng009

发件人: Ruiqi Hong
发送时间: 2012-09-29  18:25:50
收件人: golang-china
抄送:
主题: Re: [gocn:6539] 一个goroutine要消耗多少内存呢以及一个简单的测试

Ruiqi Hong

unread,
Sep 29, 2012, 6:52:07 AM9/29/12
to golang...@googlegroups.com
export GOMAXPROCS=4

zog Lee

unread,
Sep 29, 2012, 7:23:33 AM9/29/12
to golang...@googlegroups.com
rsc在 http://research.swtch.com/gotour 的Q&A里有提到(当然看Go的源码更好啦,呵呵)

具体看这两个问题:
Q. What are the limits to scalability with building a system with many goroutines?

The primary limit is the memory for the goroutines. Each goroutine starts with a 4kB stack and a little more per-goroutine data, so the overhead is between 4kB and 5kB. That means on this laptop I can easily run 100,000 goroutines, in 500 MB of memory, but a million goroutines is probably too much.

For a lot of simple goroutines, the 4 kB stack is probably more than necessary. If we worked on getting that down we might be able to handle even more goroutines. But remember that this is in contrast to C threads, where 64 kB is a tiny stack and 1-4MB is more common.


Q. Do goroutine stacks adapt in size?
The initial stack allocated for a goroutine does not adapt. It’s always 4k right now. It has been other values in the past but always a constant. One of the things I’d like to do is to look at what the goroutine will be running and adjust the stack accordingly, but I haven’t.


另外可能要注意的是goroutine的最小内存是4k的栈空间,如果另外用了内存就更多了,哈哈



2012/9/29 damacheng009 <damach...@gmail.com>

--

minux

unread,
Sep 29, 2012, 8:00:54 AM9/29/12
to golang...@googlegroups.com
创建一个goroutine的内存消耗大头是它的堆栈,上面那个文件的若干常量决定了初始堆栈多大。

PS:创建goroutine的runtime代码在tip.golang.org/src/pkg/runtime/proc.c,有兴趣的看吧,结论是
goroutine的堆栈初始堆栈大小是StackMin+StackSystem。

关于内存回收的问题,目前的策略是如果一整个MSpan在GC之后5分钟内都一直是没用的状态,
那么返还给操作系统。但是注意是MSpan一起返还,如果有内存碎片的话,那就不行了。目前
Go的GC还不会compact。(这部分代码在tip.golang.org/src/pkg/runtime/mheap.c

minux

unread,
Sep 29, 2012, 8:11:21 AM9/29/12
to golang...@googlegroups.com

2012/9/29 zog Lee <zog...@gmail.com>

rsc在 http://research.swtch.com/gotour 的Q&A里有提到(当然看Go的源码更好啦,呵呵)

具体看这两个问题:
Q. What are the limits to scalability with building a system with many goroutines?

The primary limit is the memory for the goroutines. Each goroutine starts with a 4kB stack and a little more per-goroutine data, so the overhead is between 4kB and 5kB. That means on this

既然你引用了这个数据,我就写明白具体的答案吧。

其实rsc说的不完全准确(因为我确定他不在Windows上开发Go [八卦下,似乎他台式机跑Mac OS X,笔记本跑
Linux],所以他说的这个对除Windows外的其他Go官方支持的操作系统都准确)。
Windows用户会比较郁闷,在Windows/386上,每个goroutine的初始堆栈大小是4KiB+2KiB,在windows/amd64
上则是4KiB+4KiB。 

Reply all
Reply to author
Forward
0 new messages