JRuby PermGen 空间不足甚至在 ruby 代码中使用 java 对象
Posted
技术标签:
【中文标题】JRuby PermGen 空间不足甚至在 ruby 代码中使用 java 对象【英文标题】:JRuby PermGen out of space even use java objects in ruby code 【发布时间】:2012-06-22 13:36:28 【问题描述】:说明:
如果我们使用 java 对象 jruby 也可以得到 permgen:
System.out.println("Initialazing..");
//Spring applicaton context
WebApplicationContext wac = (WebApplicationContext) AppContext.getApplicationContext();
// prepare path to internal ruby
String scriptsPath = wac.getServletContext().getRealPath(RUBY_PATH);
String jrubyHome = wac.getServletContext().getRealPath("WEB-INF" + File.separator + "jruby");
// Initializing Scripting container
ScriptingContainer container = new ScriptingContainer(isShared ? LocalContextScope.SINGLETHREAD
: LocalContextScope.THREADSAFE, LocalVariableBehavior.PERSISTENT);
// Configuring scriptingcontainer to avoid memory leaks
container.setCompileMode(RubyInstanceConfig.CompileMode.OFF);
System.setProperty("org.jruby.embed.compilemode", "OFF");
System.setProperty("jruby.compile.mode", "OFF");
// Setup ruby version
container.setCompatVersion(CompatVersion.RUBY1_9);
// Set jruby home
container.getProvider().getRubyInstanceConfig().setJRubyHome(jrubyHome);
List<String> loadPaths = new ArrayList<String>();
// load path
loadPaths.add(scriptsPath);
container.getProvider().setLoadPaths(loadPaths);
// ruby dispatcher initializing and run in simple mood
String fileName = scriptsPath + File.separator + "dispatcher_fake.rb";
// run scriplet
container.runScriptlet(PathType.ABSOLUTE, fileName);
// terminate container to cleanup memory without any effects
container.terminate();
container=null;
小脚本:
ENV['GEM_PATH'] = File.expand_path('../../jruby/1.9', __FILE__)
ENV['GEM_HOME'] = File.expand_path('../../jruby/1.9', __FILE__)
ENV['BUNDLE_BIN_PATH'] = File.expand_path('../../jruby/1.9/gems/bundler-1.0.18/bin/bundle', __FILE__)
require 'java'
ROOT_DIR = File.dirname(__FILE__)
require File.join(ROOT_DIR, "base", "xsi.rb")
# require java classes
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
module JavaListing
include_package "com.util.listing"
end
class A
include JavaListing
def run
1000.times do |index|
puts "iterating #index"
# java class property
prop = JavaListing::Property.new
prop.proNo = 111
prop.remoteID = "1111"
prop.ownerID = "1111"
prop.advertiserID = "1111"
prop.title = "Atite"
prop.summary = "Asummury"
prop.description = "Adescription"
# prop.images << JavaListing::Image.new("111", "Acaption")
prop.lat = 12.23
prop.lng = 13.21
#prop.address = JavaListing::Address.new("Acity", "Acountry")
prop.location = "Alocation"
prop.policy = JavaListing::Policy.new("AcheckinAt", "AcheckoutAt")
prop.surfaceArea = "Asurfscearea"
# prop.notes[index] = JavaListing::Note.new("Atitle", "Atext")
prop.order = "Aorder"
prop.map = JavaListing::Map.new(true, 14)
#
doc = Jsoup.parse("<root><elements><element>Application Error #index </element></elements></root>")
end
end
如您所见,我们使用了所有 java 对象,但 Perm 仍然会发生内存泄漏问题
如果我们在 Spring 应用程序中创建对象并将 Application Context 传递给 ruby 以便将来获取 bean,这并不能解决此问题
在脚本容器中设置 ApplicationContext context = Spring application context
container.put("$context", context);
红宝石代码
bean = $context.getBean("some_name")
bean.myMethod()
【问题讨论】:
【参考方案1】:解决方案是使用从当前 JVM 启动的单独 JVM:
Start new JVM
【讨论】:
以上是关于JRuby PermGen 空间不足甚至在 ruby 代码中使用 java 对象的主要内容,如果未能解决你的问题,请参考以下文章
我出现内存不足错误,如何解决?Permgen 空间区域是啥意思?是啥原因造成的? [复制]
如何在 Tomcat 中部署之前监控 PermGen 空间使用情况