1 回答
TA贡献1784条经验 获得超8个赞
pprof可以告诉你在哪里花费了内存。只需为net/http/pprof包添加一个导入语句,并使用 http.DefaultServeMux 启动一个 HTTP 服务器:
import _ "net/http/pprof"
func main() {
go func() { log.Fatal(http.ListenAndServe(":4000", nil)) }()
//...
}
在程序运行时,运行 pprof 工具来查看有关程序的各种统计信息。由于您关心内存使用情况,因此堆配置文件(使用中的内存)可能是最相关的。
$ go tool pprof -top 10 http://localhost:4000/debug/pprof/heap
Fetching profile over HTTP from http://localhost:4000/debug/pprof/heap
File: foo
Build ID: 10
Type: inuse_space
Time: Dec 21, 2018 at 12:52pm (CET)
Showing nodes accounting for 827.57MB, 99.62% of 830.73MB total
Dropped 9 nodes (cum <= 4.15MB)
flat flat% sum% cum cum%
778.56MB 93.72% 93.72% 796.31MB 95.86% time.NewTimer
18.25MB 2.20% 95.92% 18.25MB 2.20% time.Sleep
17.75MB 2.14% 98.05% 17.75MB 2.14% time.startTimer
11MB 1.32% 99.38% 11MB 1.32% runtime.malg
2MB 0.24% 99.62% 798.31MB 96.10% main.(*Session).readLoop
0 0% 99.62% 798.31MB 96.10% main.(*Session).Serve
0 0% 99.62% 18.25MB 2.20% main.(*Session).sendLoop
0 0% 99.62% 800.81MB 96.40% main.Loop
0 0% 99.62% 11.67MB 1.40% runtime.mstart
0 0% 99.62% 11.67MB 1.40% runtime.newproc.func1
0 0% 99.62% 11.67MB 1.40% runtime.newproc1
0 0% 99.62% 11.67MB 1.40% runtime.systemstack
0 0% 99.62% 796.31MB 95.86% time.After
time.Timer
不出所料,您创建的大量stime.After
占用了几乎所有正在使用的内存。
想一想:使用 250 毫秒的时间间隔,您创建计时器的速度比使用 1 秒的时间间隔快 4 倍。然而,计时器的寿命与间隔不成比例——它恒定为 60 秒。因此,在任何给定时间点,您有 4*60=240 倍以上的计时器处于活动状态。
来自 time.After 的文档:
等待持续时间过去后,然后在返回的通道上发送当前时间。它等同于 NewTimer(d).C。在计时器触发之前,垃圾收集器不会回收底层计时器。如果效率是一个问题,请改用 NewTimer 并在不再需要计时器时调用 Timer.Stop。
因此,为每个创建一个计时器readLoop
并重新使用它。您可以通过使用空结构值通道而不是布尔值通道来进一步减少内存使用:
type Session struct {
KeepAlive chan struct{}
}
func (s *Session) readLoop() {
fmt.Println("readLoop")
d := 1 * time.Minute
t := time.NewTimer(d)
loop:
for {
select {
case _, ok := <-s.KeepAlive:
if !ok {
break loop
}
if !t.Stop() {
<-t.C
}
t.Reset(d)
case <-t.C:
fmt.Println("Timeout")
break loop
}
}
fmt.Println("readLoop EXIT")
}
func (s *Session) sendLoop() {
defer close(s.KeepAlive)
for {
s.KeepAlive <- struct{}{}
time.Sleep(interval)
}
}
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报