Memory JRuby上对虾的主要内存使用问题

Memory JRuby上对虾的主要内存使用问题,memory,jruby,prawn,jrubyonrails,torquebox,Memory,Jruby,Prawn,Jrubyonrails,Torquebox,在Rails和Torquebox上使用Prawn和JRuby编译大型文档(数百页以上)时,我们遇到了严重的内存使用问题 我们的应用程序基本上允许用户上传一堆PDF文档并将它们整理成一个。Prawn部分获取文件列表,逐页循环,通过document将每一页插入我们的输出文档。启动新页面(模板:'filename'),并在插入后对每一页进行一些小的添加(绘图页码和选项卡)。下面复制了一些相关代码 虽然我们正在生成的一些文件相当大,但内存使用似乎仍然不成比例。例如,生成一个38MB的文件需要超过4GB的

在Rails和Torquebox上使用Prawn和JRuby编译大型文档(数百页以上)时,我们遇到了严重的内存使用问题

我们的应用程序基本上允许用户上传一堆PDF文档并将它们整理成一个。Prawn部分获取文件列表,逐页循环,通过
document将每一页插入我们的输出文档。启动新页面(模板:'filename')
,并在插入后对每一页进行一些小的添加(绘图页码和选项卡)。下面复制了一些相关代码

虽然我们正在生成的一些文件相当大,但内存使用似乎仍然不成比例。例如,生成一个38MB的文件需要超过4GB的RAM(!)。这个特定的文件是通过整理30个文件创建的,其中最大的两个文件大小分别为7MB和5MB,大多数文件只有100KB,但我们必须将Java的heapsize增加到5GB,以防止服务器崩溃

我们的内存使用率如此之高,我们是否应该感到惊讶?我们做错什么了吗?有解决办法吗?非常感谢

我们的服务器设置:

JRuby版本:1.7.4 Rails版本:4.0.0,在生产模式下运行 扭矩箱:3.0.0 操作系统:Ubuntu 12.04 LTS 对虾版本:1.0.0rc2 JAVA_OPTS:-server-XX:+UseCompressedOops-Xms512m-Xmx5000m-XX:MaxPermSize=512m-Djava.net.preferIPv4Stack=true-Djboss.modules.system.pkgs=org.jboss.byteman-Djava.awt.headless=true

下面是代码中最相关的部分:
add_file()
对每个输入文件调用一次。注意,有一个对
@document.start\u new\u page()
的调用,它实际上会插入一个新页面,然后是对
start\u new\u page()
的调用,它不会插入一个新页面,但会确保正确设置
page.dictionary.date
。我不知道这是否与我们的记忆问题有关

  def create_or_update_document(opts)
    if @document
      @document.start_new_page(opts)
    else
      opts[:margin] = 0
      @document = Prawn::Document.new(opts)   
      @document.font_size 12
    end
  end

  def add_file(file)
    puts "     add_file() filename=#{file['full_path']}"

    filename = file['full_path']
    num_pages = file['pagecount']

    (1..num_pages).each do |page_number|
      puts "     Adding page: #{page_number}"

      # take the page defined in file 'filename' and insert it into the 
      # @document we're building
      create_or_update_document(:template => filename, :template_page => page_number)

      # this call to start_new_page doesn't change our @document, but
      # it ensures that 'page.dictionary.data' contains the settings
      # (:Rotate, etc) from the source PDF
      start_new_page(:template => filename, :template_page => page_number)

      puts "      Page size: width=#{page_width} height=#{page_height} Rotate: #{page.dictionary.data[:Rotate]}"


      # add destination for internal links e.g. from table of contents or tabs
      @document.add_dest("page#{@current_page_number}", @document.dest_fit)

      rotation = page.dictionary.data[:Rotate]
      case rotation
      when 90
        translate_x = 0
        translate_y = -page_width
        page_number_x = page_height - RightMargin
        tab_page_height = page_width

      when 180
        translate_x = -page_width
        translate_y = -page_height
        page_number_x = page_width - RightMargin
        tab_page_height = page_height

      when 270
        translate_x = -page_height
        translate_y = 0
        page_number_x = page_height - RightMargin
        tab_page_height = page_width

      else
        translate_x = 0
        translate_y = 0
        rotation = 0
        page_number_x = page_width - RightMargin
        tab_page_height = page_height
      end

      @document.rotate(rotation, :origin => [0,0]) do
        @document.translate(translate_x,translate_y) do
          if @pack.include_tabs
            add_tabs(tab_page_height, page_number_x, @current_page_number)
          end
          @document.text_box "<font name='Georgia' size='12'>#{@current_page_number}</font>", at: [page_number_x, BottomMargin + 14], inline_format: true, width: RightMargin + 100
        end
      end

      @current_page_number = @current_page_number + 1
    end
  end
def创建或更新文档(opts)
如果@文档
@文档。开始新页面(opts)
其他的
选项[:边距]=0
@document=Prawn::document.new(opts)
@document.font\u大小12
结束
结束
def添加_文件(文件)
放置“add_file()filename=#{file['full_path']}”
filename=file['full_path']
num_pages=文件['pagecount']
(1..num_页数)。每个do|页码|
放入“添加页面:{page_number}”
#获取文件“filename”中定义的页面并将其插入
#@我们正在构建的文档
创建或更新文档(:template=>文件名,:template\u page=>页码)
#这个启动新页面的调用不会改变我们的@document,但是
#它确保“page.dictionary.data”包含设置
#(:旋转等)从源PDF
开始新页面(:模板=>文件名,:模板页面=>页码)
将“页面大小:宽度=#{Page_width}高度=#{Page_height}旋转:#{Page.dictionary.data[:Rotate]}”
#添加内部链接的目的地,例如从目录或选项卡
@document.add_dest(“page#{@current_page_number},@document.dest_fit)
旋转=页面.字典.数据[:旋转]
案例轮换
90岁时
平移_x=0
translate_y=-页面宽度
页码=页码高度-右边距
选项卡\页面\高度=页面\宽度
当180
translate_x=-页面宽度
translate_y=-页面高度
页码\u x=页码\u宽度-右边距
选项卡页面高度=页面高度
当270
translate_x=-页面高度
平移_y=0
页码=页码高度-右边距
选项卡\页面\高度=页面\宽度
其他的
平移_x=0
平移_y=0
旋转=0
页码\u x=页码\u宽度-右边距
选项卡页面高度=页面高度
结束
@document.rotate(rotation,:origin=>[0,0])do
@翻译(translate_x,translate_y)做什么
如果@pack.include_选项卡
添加标签(标签页高度、页码、当前页码)
结束
@document.text_框“#{@current_page_number}”,位于:[page_number_x,BottomMargin+14],内联_格式:true,宽度:RightMargin+100
结束
结束
@当前页面号=@当前页面号+1
结束
结束