Forum: Ruby PDF::Writer running out of memory

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cfdeff3ac35010e4de8f85d954f24f4a?d=identicon&s=25 Damphyr (Guest)
on 2006-02-01 19:01
(Received via mailing list)
I have a bunch of XML files containing specifications and I want to
create a PDF file with an overview of the description element from those
XML files.
I parse the XML and convert it into a Spec object than I create the PDF
using some attributes.
Now, the following code runs out of memory at about 53 out of 87 of
those specs.
header and footer add a line and a bit of text (it's actually code
adapted from the PDF::Writer Manual Techbook :) )

def create
   #creation time
   @time=Time.now.strftime("%d/%m/%Y - %H:%M")
   #main title/front page
   title
   #page header
   header
   #page footer
   footer
   @pdf.start_new_page
   @pdf.start_page_numbering(@pdf.absolute_right_margin, 36, 6,:right)
   specifications.each do |s|
     puts "doing #{s.name}"
     spec_table(s).render_on(@pdf)
   end
   return
end

def spec_table spec
   table=PDF::SimpleTable.new
   table.column_order=["row"]
   table.title=spec.title
   table.data=[{"row"=>spec.description}]
   table.show_headings=false
   table.width=@pdf.margin_width
   table.header_gap=20
   return table
end

Below is the backtrace.
Now before you all scream, I did reuse the SimpleTable object to avoid
instantiating it for every spec. This did not make much difference,
since the script run out of memory at exactly the same place.
Is there a solution to this problem or do I need to work around it?
Is there a workaround that gives me a single PDF at the end?
All I can think about now is breaking the overview doc in several
pieces.
Keep in mind that the number of specs is only going to grow in the
future.
Cheers,
V.-

-----------
d:/dev/ruby/lib/ruby/gems/1.8/gems/transaction-simple-1.3.0/lib/transaction/simple.rb:370:in
`dump': failed to allocate memory (NoMemoryError) from
d:/dev/ruby/lib/ruby/gems/1.8/gems/transaction-simple-1.3.0/lib/transaction/simple.rb:370:in
`start_transaction'from
d:/dev/ruby/lib/ruby/gems/1.8/gems/transaction-simple-1.3.0/lib/transaction/simple/group.rb:89:in
  `start_transaction'from
d:/dev/ruby/lib/ruby/gems/1.8/gems/transaction-simple-1.3.0/lib/transaction/simple/group.rb:89:in
  `each'from
d:/dev/ruby/lib/ruby/gems/1.8/gems/transaction-simple-1.3.0/lib/transaction/simple/group.rb:89:in
  `start_transaction' from
d:/dev/ruby/lib/ruby/gems/1.8/gems/pdf-writer-1.1.3/lib/pdf/simpletable.rb:497:in
`render_on' from
d:/dev/ruby/lib/ruby/gems/1.8/gems/pdf-writer-1.1.3/lib/pdf/simpletable.rb:488:in
`each' from
d:/dev/ruby/lib/ruby/gems/1.8/gems/pdf-writer-1.1.3/lib/pdf/simpletable.rb:488:in
`render_on' from
d:/dev/ruby/lib/ruby/gems/1.8/gems/pdf-writer-1.1.3/lib/pdf/simpletable.rb:401:in
`loop' from
d:/dev/ruby/lib/ruby/gems/1.8/gems/pdf-writer-1.1.3/lib/pdf/simpletable.rb:401:in
`render_on' from ./test.rb:524:in `create' from ./test.rb:522:in `each'
from d:/dev/ruby/lib/ruby/gems/1.8/gems/rake-0.7.0/lib/rake.rb:844:in
`send'        from
d:/dev/ruby/lib/ruby/gems/1.8/gems/rake-0.7.0/lib/rake.rb:844:in `each'
from ./test.rb:522:in `create' from ./test.rb:493:in `overview' from
overview.rb:72
--
http://www.braveworld.net/riva
31ab75f7ddda241830659630746cdd3a?d=identicon&s=25 Austin Ziegler (Guest)
on 2006-02-01 19:58
(Received via mailing list)
On 01/02/06, Damphyr <damphyr@freemail.gr> wrote:
> I have a bunch of XML files containing specifications and I want to
> create a PDF file with an overview of the description element from
> those XML files. I parse the XML and convert it into a Spec object
> than I create the PDF using some attributes. Now, the following code
> runs out of memory at about 53 out of 87 of those specs. header and
> footer add a line and a bit of text (it's actually code adapted from
> the PDF::Writer Manual Techbook :) )

I have had someone else report this and provide me with a customized
SimpleTable that drastically reduces the memory usage but drops
some...recoverability; it does not surprise me that this is happening,
but I have had no time to investigate exactly what can be done. It does
not surprise me that this is happening, and there may be several ways to
solve this.

The problem is best shown with code:

  require 'transaction/simple'

  class Parent
    include Transaction::Simple

    attr_accessor :children
    def add_children(*children)
      children.each { |x|
        x.parent = self
        @children << x
      }
    end
    def initialize
      @children = []
    end
  end

  class Child
    attr_accessor :parent
  end

  def show_ids(parent)
    puts <<-EOS
  self <#{parent.object_id}> [ #{parent.children.map do |el|
    el.parent.object_id end.join(', ') } ]
    EOS
  end

  a = Parent.new
  a.add_children Child.new ; nil
  show_ids(a) # self<24875792> [ 24875792 ]
  a.start_transaction ; nil
  a.add_children Child.new, Child.new ; nil
  show_ids(a) # self<24875792> [ 24875792, 24875792, 24875792 ]
  a.rewind_transaction ; nil
  a.add_children Child.new, Child.new ; nil
  show_ids(a) # self<24875792> [ 24852044, 24875792, 24875792 ]

That last one is the source of the memory leak. It's also the source of
a much more subtle bug in the making it impossible to set certain things
"late" in the process.

-austin
This topic is locked and can not be replied to.