类似如图程序,请求后发现程序占用了非常大的内存,并且请求结束后也没有清除内存。
请问如何才能实现每次请求后即时清除这一片变量内存?
![carbon.png](https://static.studygolang.com/210308/7b394efc0ee25d33e08e02dc6af32e4a.png)
![Snipaste_2021-03-08_17-56-40.png](https://static.studygolang.com/210308/00130f73e8ecccd24bc395428cdcd79a.png)
如果里面的内容全都是要即时可用,但有大量重复,可以直接共享缓存。多线程之间共享资源。
如果都是非即时可用,但又不得不用,可以上nosql数据库做缓存,然后单线程资源使用完丢弃,让GC回收
#5
更多评论
回答问题:没有办法立即释放slice占用的内存。因为go的GC没有使用引用计数的机制,所以即使tmp=nil也是不行的。
如何优化:我们进入到这个场景中来,这里有一个API,每次请求它时都要创建一个slice,并往里面存放可预估长度的大量的数据。这些数据是一次性的,用完丢弃。但是每次请求时所需的slice空间基本是相等的。 所以,这里我们需要构建一个临时的内存池,即1个可复用的slice。上代码
```
package main
import (
"net/http"
"testing"
)
var tmp = make([]int, 0, 32*1000000)
func f() {
println("enter...")
for i := 0; i < 32*1000000; i++ {
tmp = append(tmp, i)
}
tmp = tmp[:0]
println("done")
}
func ff(w http.ResponseWriter, r *http.Request) {
f()
}
func TestSlice(t *testing.T) {
http.HandleFunc("/x", ff)
panic(http.ListenAndServe(":1001", nil))
}
```
这样就可以使内存占用稳定在一个指标;避免了每请求1次,内存占用就累加1次,从而造成严重的内存泄露事件。
#2