Joh*_*ith 2 memory garbage-collection http go server
我正在使用以下功能下载小于20MB的文件.它将整个内容读取到内存中,因为另一个函数必须在将字节写入磁盘之前对字节执行操作.
func getURL(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("getURL: %s", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("getURL: %s", err)
}
return body, nil
}
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作,但系统会消耗所有内存.
是否可以释放body由其他函数处理后使用的内存,因此内存使用量不会大于当前正在处理的字节数?
首先,我建议您阅读以下问题/答案:
Golang - 一旦被bytes.Buffer占用就无法释放内存
您可以触发gc来释放未使用的对象,runtime.GC()并且您可能会敦促Go运行时将内存释放回操作系统debug.FreeOSMemory(),但所有这些只是消防.一个写得很好的Go应用程序永远不必调用这些.
您应该做的是防止运行时必须分配大量内存.
你怎么能实现这个目标?一些方法(你甚至可以结合这些解决方案):
限制服务需要大内存的请求,更多关于它:Go Webserver的进程管理 ; 也这是围棋的习惯工作者线程池?
使用内存/缓冲池,不要一直分配大数组/切片,更多关于它:如何在Golang中实现内存池
创建/更改处理单元不要在字节片上操作,而是在io.Readers上操作,因此您不需要将所有内容读入内存,您可以直接传递resp.Body.请注意,即使多个单元必须读取/检查主体,仍然可以只读取和处理一次,而不是将其保留在内存中.手段可能是io.Pipe(),io.TeeReader()或定制解决方案.
| 归档时间: |
|
| 查看次数: |
458 次 |
| 最近记录: |