浏览代码

Delayed download buffer grow

DarthSim 2 年之前
父节点
当前提交
ad5bd69f80
共有 3 个文件被更改,包括 22 次插入7 次删除
  1. 2 0
      CHANGELOG.md
  2. 6 3
      bufpool/bufpool.go
  3. 14 4
      imagedata/read.go

+ 2 - 0
CHANGELOG.md

@@ -1,6 +1,8 @@
 # Changelog
 # Changelog
 
 
 ## [Unreleased]
 ## [Unreleased]
+### Fix
+- Fix memory bloat in some cases.
 
 
 ## [3.7.0] - 2022-07-27
 ## [3.7.0] - 2022-07-27
 ### Add
 ### Add

+ 6 - 3
bufpool/bufpool.go

@@ -73,7 +73,7 @@ func (p *Pool) calibrateAndClean() {
 	metrics.SetBufferMaxSize(p.name, p.maxSize)
 	metrics.SetBufferMaxSize(p.name, p.maxSize)
 }
 }
 
 
-func (p *Pool) Get(size int) *bytes.Buffer {
+func (p *Pool) Get(size int, grow bool) *bytes.Buffer {
 	p.mutex.Lock()
 	p.mutex.Lock()
 	defer p.mutex.Unlock()
 	defer p.mutex.Unlock()
 
 
@@ -115,7 +115,10 @@ func (p *Pool) Get(size int) *bytes.Buffer {
 
 
 	buf.Reset()
 	buf.Reset()
 
 
-	growSize := imath.Max(size, p.defaultSize)
+	growSize := p.defaultSize
+	if grow {
+		growSize = imath.Max(size, growSize)
+	}
 
 
 	if growSize > buf.Cap() {
 	if growSize > buf.Cap() {
 		buf.Grow(growSize)
 		buf.Grow(growSize)
@@ -145,7 +148,7 @@ func (p *Pool) Put(buf *bytes.Buffer) {
 		if b == nil {
 		if b == nil {
 			p.buffers[i] = buf
 			p.buffers[i] = buf
 
 
-			if buf.Cap() > 0 {
+			if buf.Len() > 0 {
 				metrics.ObserveBufferSize(p.name, buf.Cap())
 				metrics.ObserveBufferSize(p.name, buf.Cap())
 			}
 			}
 
 

+ 14 - 4
imagedata/read.go

@@ -44,7 +44,7 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
 		return nil, ErrSourceFileTooBig
 		return nil, ErrSourceFileTooBig
 	}
 	}
 
 
-	buf := downloadBufPool.Get(contentLength)
+	buf := downloadBufPool.Get(contentLength, false)
 	cancel := func() { downloadBufPool.Put(buf) }
 	cancel := func() { downloadBufPool.Put(buf) }
 
 
 	if config.MaxSrcFileSize > 0 {
 	if config.MaxSrcFileSize > 0 {
@@ -54,17 +54,27 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
 	br := bufreader.New(r, buf)
 	br := bufreader.New(r, buf)
 
 
 	meta, err := imagemeta.DecodeMeta(br)
 	meta, err := imagemeta.DecodeMeta(br)
-	if err == imagemeta.ErrFormat {
-		return nil, ErrSourceImageTypeNotSupported
-	}
 	if err != nil {
 	if err != nil {
+		buf.Reset()
+		cancel()
+
+		if err == imagemeta.ErrFormat {
+			return nil, ErrSourceImageTypeNotSupported
+		}
+
 		return nil, checkTimeoutErr(err)
 		return nil, checkTimeoutErr(err)
 	}
 	}
 
 
 	if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil {
 	if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil {
+		buf.Reset()
+		cancel()
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	if contentLength > buf.Cap() {
+		buf.Grow(contentLength - buf.Len())
+	}
+
 	if err = br.Flush(); err != nil {
 	if err = br.Flush(); err != nil {
 		cancel()
 		cancel()
 		return nil, checkTimeoutErr(err)
 		return nil, checkTimeoutErr(err)