JRuby PermGen空间不足甚至在ruby代码中使用java对象

描述:

如果我们使用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 loadPaths = new ArrayList(); // 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("Application Error #{index} ") end end 

正如您所看到的,我们正在使用所有Java对象,但Perm仍然会发生内存泄漏

如果我们在spring应用程序中创建对象并将Application Context传递给ruby以便将来获取bean,那么这并没有解决这个问题

在脚本容器中设置ApplicationContext context = Spring应用程序上下文

 container.put("$context", context); 

ruby代码

 bean = $context.getBean("some_name") bean.myMethod() 

解决方案是使用从当前JVM启动的单独JVM:

启动新的JVM