diff options
author | Aliaksandr Valialkin <valyala@gmail.com> | 2017-05-17 14:35:37 +0300 |
---|---|---|
committer | Aliaksandr Valialkin <valyala@gmail.com> | 2017-05-17 14:45:31 +0300 |
commit | 30e92af08fad62919ff2eae84f530a2f52a547c3 (patch) | |
tree | 5a565c9ac513e70971d495f5a32d1e3ac36bf91f /fs.go | |
parent | client: properly extract tls ServerName from address without port (diff) | |
download | fasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.tar.gz fasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.tar.bz2 fasthttp-30e92af08fad62919ff2eae84f530a2f52a547c3.zip |
Limit heap memory usage when compressing high number of concurrent responses
Previously each concurrent compression could allocate huge compression state
with the size up to 1Mb each. So 10K concurrent connections could result in
10Gb of compression state in the heap.
This CL limits the number of compression states among concurrent requests
when {Append,Write}{Gzip,Deflate}* functions are called to O(GOMAXPROCS).
These functions are used by CompressHandler* for non-streaming responses,
i.e. it should cover the majority of use cases.
Memory usage for 10K concurrent connections that compress responses drops
from 10Gb to 200Mb after this CL.
Diffstat (limited to 'fs.go')
-rw-r--r-- | fs.go | 11 |
1 files changed, 3 insertions, 8 deletions
@@ -958,12 +958,7 @@ func (h *fsHandler) createDirIndex(base *URI, dirPath string, mustCompress bool) if mustCompress { var zbuf ByteBuffer - zw := acquireGzipWriter(&zbuf, CompressDefaultCompression) - _, err = zw.Write(w.B) - releaseGzipWriter(zw) - if err != nil { - return nil, fmt.Errorf("error when compressing automatically generated index for directory %q: %s", dirPath, err) - } + zbuf.B = AppendGzipBytesLevel(zbuf.B, w.B, CompressDefaultCompression) w = &zbuf } @@ -1048,12 +1043,12 @@ func (h *fsHandler) compressFileNolock(f *os.File, fileInfo os.FileInfo, filePat return nil, errNoCreatePermission } - zw := acquireGzipWriter(zf, CompressDefaultCompression) + zw := acquireStacklessGzipWriter(zf, CompressDefaultCompression) _, err = copyZeroAlloc(zw, f) if err1 := zw.Flush(); err == nil { err = err1 } - releaseGzipWriter(zw) + releaseStacklessGzipWriter(zw, CompressDefaultCompression) zf.Close() f.Close() if err != nil { |