Skip to content

Feature request: reduce the Max RSS in streaming inflate #19

@harryqingyuzhao

Description

@harryqingyuzhao

While it is great to have streaming support in inflating processing, the max RSS could be a little high, depends on GC frequency.

  1. if we add manual GC cycle during streaming inflate, it reduces the max RSS from 150M to 26M.
  2. if use gunzip, the max RSS is only 872K.

Question: can we further reduce the max RSS of streaming inflate? It seems we are using RB_ALLOC. While GC may not timely free the memory. Can we RB_ALLOC a small buffer, and reuse the same buffer without RB_ALLOC new buffer again?

Test steps:

$ dd if=/dev/zero of=/dev/stdout bs=1m count=1024 | gzip -c > 1G.gz

$ cat test.rb

require 'zlib'

f = File.open '1G.gz'

z = Zlib::Inflate.new Zlib::MAX_WBITS + 32

step = 0
total = 0

until f.eof? do
  gzipped = f.read(4096)
  z.inflate gzipped do |chunk|
    total += chunk.size

    step += 1
    # GC.start if step % 100 == 0 # commont out this line to see larger `max rss`
  end
end

puts "total: #{total}"

z.finish
# end of test.rb

The max RSS is around 150M

$ /usr/bin/time -l ruby test.rb
total: 1073741824
2.26 real 2.12 user 0.13 sys
156069888 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
81828 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
0 voluntary context switches
930 involuntary context switches

Uncomment the line GC.start if step % 100 == 0, with more GC invoked, the max RSS is reduced to around 26M.

$ /usr/bin/time -l ruby test.rb
total: 1073741824
2.74 real 2.70 user 0.03 sys
26480640 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
6517 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
1 voluntary context switches
862 involuntary context switches

Compare to gunzip. The max RSS is only 870K when using gunzip.

$ /usr/bin/time -l gunzip 1G.gz
1.58 real 1.23 user 0.28 sys
872448 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
236 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
138 voluntary context switches
176 involuntary context switches

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions