释放未使用的内存? [英] Freeing unused memory?
问题描述
我使用以下功能下载小于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
}
这可以正常工作,但所有内存都在系统上消耗。
是否有可能释放由 body
使用的内存在被另一个函数处理后,因此内存使用量不会大于当前正在处理的字节首先,我建议阅读下面的问题/答案:
$ b
戈兰 - 无法释放曾经占据bytes.Buffer的内存, p>
您可以使用 runtime.GC()
,你可能会促使你的Go运行时通过 debug.FreeOSMemory()
,但所有这些只是消防。一个写得很好的Go应用程序不应该调用它们。
你应该做的是防止运行时分配大量内存。
你怎么做到这一点?一些手段(你甚至可以合并这些解决方案):
-
限制服务需要大内存的请求,更多关于它的内容: Go Webserver的流程管理;也是这是一个惯用的工作线程池在Go ?
- b $ b
-
创建/更改处理单元不要在字节切片上操作,但在
io.Reader
s,所以你不需要读取所有内容到内存中,你可以传递resp.Body
打开。请注意,即使多个单元必须读取/检查主体,仍然只能读取和处理一次,而不能将其保存在内存中。手段可能是io.Pipe()
,io.TeeReader()
或定制解决方案。
I'm using the following function for downloading files smaller than 20MB. It read the entire content to memory as another function has to perform work on the bytes before it can be written to disk.
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
}
This works fine, but all memory is consumed on the system.
Is it possible to release memory used by body
after it has been processed by another function, so memory use won't be larger than the bytes currently being processed?
First I recommend to read the following questions / answers:
Golang - Cannot free memory once occupied by bytes.Buffer
You may trigger a gc to free unused objects with runtime.GC()
and you may urge your Go runtime to release memory back to OS with debug.FreeOSMemory()
, but all these are just fire fighting. A well-written Go app should never have to call these.
What you should do is prevent the runtime having to allocate large amount of memory.
How may you achieve this? Some means (you can even combine these solutions):
Limit serving the requests requiring large memory, more about it: Process Management for the Go Webserver; also Is this an idiomatic worker thread pool in Go?
Use memory / buffer pools, do not allocate big arrays / slices all the time, more about it: How to implement Memory Pooling in Golang
Create / change your processing units not to operate on byte slices but on
io.Reader
s, so you don't need to read all content into memory, you can just passresp.Body
on. Note that even if multiple units have to read / inspect the body, it is still possible to only read and process it once, and not keep it in memory. Means may beio.Pipe()
,io.TeeReader()
or custom solutions.
这篇关于释放未使用的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!