我最近在Tomcat中使用JRuby运行Sinatra时遇到了Permgen内存泄漏问题。 该问题与Sinatra使用的Tilt库支持各种模板选项有关。 老代码(未包含在此处)生成了内存泄漏。 新代码(如下)没有,事实上我看到Permgen GC现在正在工作。
Ruby应该是自描述的,但我无法通过阅读它来解释这段代码。 为什么会有嵌套的类eval? 为什么定义一个方法然后解除绑定?
编译一堆模板并使它们保持可重用的代码为什么看起来如此复杂?
另外:如果有任何GitHub员工查看这个问题,请添加一些功能,允许用户在代码片段中插入问题。
(此代码摘自https://github.com/rtomayko/tilt/blob/master/lib/tilt.rb)
Ruby应该是自描述的,但我无法通过阅读它来解释这段代码。 为什么会有嵌套的类eval? 为什么定义一个方法然后解除绑定?
编译一堆模板并使它们保持可重用的代码为什么看起来如此复杂?
另外:如果有任何GitHub员工查看这个问题,请添加一些功能,允许用户在代码片段中插入问题。
(此代码摘自https://github.com/rtomayko/tilt/blob/master/lib/tilt.rb)
def compile_template_method(locals)
source, offset = precompiled(locals)
offset += 5
method_name = "__tilt_#{Thread.current.object_id.abs}"
Object.class_eval <<-RUBY, eval_file, line - offset
#{extract_magic_comment source}
TOPOBJECT.class_eval do
def #{method_name}(locals)
Thread.current[:tilt_vars] = [self, locals]
class << self
this, locals = Thread.current[:tilt_vars]
this.instance_eval do
#{source}
end
end
end
end
RUBY
unbind_compiled_method(method_name)
end