亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

編碼 base64 時的內存消耗

編碼 base64 時的內存消耗

Go
慕森王 2022-10-31 15:47:17
我在使用 golangs lib encoding/base64 的軟件中遇到內存消耗問題我的軟件將視頻文件拆分為單獨的圖像,(gocv mat)將它們轉換為base64字符串并將其保存為json格式的文件。在測試過程中,我發現內存使用量一直在增加,直到 oom-reaper 殺死進程。對 pprof 的調查顯示編碼/base64 內存似乎堆積了起來。我在每個圖像幀之后進行了 pprof 快照,并且分配的編碼/base64 內存在 oom-reaper 終止進程之前不久從 976.89kB(flat) 增加到 4633.54kB(flat)。Beginning:      flat  flat%   sum%        cum   cum%  976.89kB 32.29% 32.29%   976.89kB 32.29%  encoding/base64.(*Encoding).EncodeToString  512.50kB 16.94% 49.23%   512.50kB 16.94%  runtime.allocm  512.20kB 16.93% 66.15%   512.20kB 16.93%  runtime.malg  512.05kB 16.92% 83.08%  1488.94kB 49.21%  runtime.main     512kB 16.92%   100%      512kB 16.92%  time.resetTimer (inline)         0     0%   100%   976.89kB 32.29%  main.ProcessEnd:Showing nodes accounting for 6170.44kB, 100% of 6170.44kB total      flat  flat%   sum%        cum   cum% 4633.54kB 75.09% 75.09%  4633.54kB 75.09%  encoding/base64.(*Encoding).EncodeToString 1024.41kB 16.60% 91.69%  1024.41kB 16.60%  runtime.malg  512.50kB  8.31%   100%   512.50kB  8.31%  runtime.allocm         0     0%   100%  4633.54kB 75.09%  main.Process列表向我顯示了與其對應的代碼:(pprof) list encoding/base64Total: 2.95MBROUTINE ======================== encoding/base64.(*Encoding).EncodeToString in /usr/local/go/src/encoding/base64/base64.go  976.89kB   976.89kB (flat, cum) 32.29% of Total         .          .    175:         .          .    176:// EncodeToString returns the base64 encoding of src.         .          .    177:func (enc *Encoding) EncodeToString(src []byte) string {         .          .    178:   buf := make([]byte, enc.EncodedLen(len(src)))         .          .    179:   enc.Encode(buf, src)  976.89kB   976.89kB    180:   return string(buf)         .          .    181:}         .          .    182:         .          .    183:type encoder struct {         .          .    184:   err  error         .          .    185:   enc  *Encoding在這種情況下,如何釋放“encodedString”的內存而不堆積?(更新:答案說這沒有必要也不可能)或者這可能不是我的錯誤編碼,并且內存泄漏位于 lib base64 中?(更新:答案說這肯定不是這種情況)
查看完整描述

2 回答

?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

要回答您的問題:

在這種情況下,如何釋放“encodedString”的內存而不堆積?

你不能也不需要。未使用的內存被“釋放”。

或者這可能不是我的錯誤編碼,而 mem-leak 位于 lib base64 ?

不,包 encoding/base64 沒有內存泄漏。(您在垃圾收集語言的標準庫中的一個普通函數中檢測到內存泄漏的可能性為 0。)

指導您找到解決方案:

您的應用程序使用了荒謬的內存量,但這是因為 a) 處理視頻和圖像占用大量內存,并且 b) 您似乎沒有采取任何措施來保持低內存:例如,您將整個圖像編碼為 bytes.Buffer,然后對整個字節進行編碼。緩沖到一個字符串,然后處理該字符串,依此類推。您可能應該將圖像編碼為stream,將此編碼為 base64 并將此輸出進一步流式傳輸到它存放的位置。這在 Go 中完全沒有痛苦,因為所有這些編碼器都在 io.Writers 上工作,可以很容易地鏈接起來。


查看完整回答
反對 回復 2022-10-31
?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

我上面的問題是完全錯誤的方式。

Base64 根本不是問題,它只是 pprof 顯示的最大內存消耗者,導致我得出一個錯誤的結論,即 base64 是問題所在。

我猜 pprof 會告訴我我的 go 程序的所有內存消耗,包括 gocv。gocv 是 opencv 的 ac 包裝器,但是 pprof 看不到它的內存消耗,因為它是 c 代碼?。ㄎ以趩栠@個問題時不知道)。由于 pprof 可見的內存消耗沒有顯示 c-wrapper 庫使用的內存,例如 gocv。golang 根本看不到大部分內存消耗。所以 JimB 的幫助提示是:

看到您如何在 opencv 周圍使用 Go 包裝器,您關心的內存可能甚至沒有被 Go 分配。在這種情況下,您確實需要確保所有內容都可能根據他們的文檔關閉或發布,因為大部分工作是在 C++ 中完成的,而不是 Go。但是,即使您正在正確清理,您仍然需要了解您的內存限制,并確保您在任何給定點都不會嘗試保存太多數據。

當我清理 gocv 對象時,內存消耗顯著下降。我曾經關閉對象:

defer obj.close()


查看完整回答
反對 回復 2022-10-31
  • 2 回答
  • 0 關注
  • 254 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號