Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Gradual increase is resident memory size when using StringBuffer  #1

@deployable

Description

@deployable

Was looking at this SO question: http://stackoverflow.com/questions/25429022/how-to-deal-with-ruby-2-1-2-memory-leaks

First test is [digest-stringbuffer][2]. Grab the example from the Readme.

require "digest/stringbuffer"
require "gc_tracer"
GC::Tracer.start_logging "log.txt"
module Digest
  class Prime31 < StringBuffer
    def initialize
      @prime = 31
    end

    def finish
      result = 0
      buffer.unpack("C*").each do |c|
        result += (c * @prime)
      end
      [result & 0xffffffff].pack("N")
    end
  end
end

And make it run lots

while true do
  a=[]
  500.times do |i|
    a.push Digest::Prime31.hexdigest( "abc" * (1000 + i) )
  end
  sleep 1
end

Run the example:

bundle exec ruby ./stringbuffertest.rb &

Monitor the resident and virtual memory sizes of the ruby process, and the count of leaks identified:

pid=123
while true; do
  ps=$(ps -o rss,vsz -p $pid | tail +2)
  leaks=$(leaks $pid | grep -c Leak)
  echo "$(date) m[$ps] l[$leaks]"
  sleep 15
done

And it looks like we've found something already:

Tue 26 Aug 2014 18:22:36 BST m[104776  2538288] l[8229]
Tue 26 Aug 2014 18:22:51 BST m[110524  2547504] l[13657]
Tue 26 Aug 2014 18:23:07 BST m[113716  2547504] l[19656]
Tue 26 Aug 2014 18:23:22 BST m[113924  2547504] l[25454]
Tue 26 Aug 2014 18:23:38 BST m[113988  2547504] l[30722]

Resident memory is increasing and the leaks tool is finding more and more unreferenced memory. Confirm the GC heap size, and object count looks stable still

tail -f log.txt | awk '{ print $1, $3, $4, $7, $13 }
1581853040832 468 183 39171 3247996
1581859846164 468 183 33190 3247996
1584677954974 469 183 39088 3254580
1584678531598 469 183 39088 3254580
1584687986226 469 183 33824 3254580
1587512759786 470 183 39643 3261058
1587513449256 470 183 39643 3261058
1587521726010 470 183 34470 3261058

It appears to my very untrained C eye that you are allocating both a pointer and a buffer but only clean up the buffer?? Not really sure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions