java - 有没有办法让 Jruby 运行时实习所有字符串?

标签 java ruby string optimization jruby

我们有一个运行在tomcat下的java/jruby webapp,我一直在分析app在运行时的对象数和内存使用情况。我注意到启动后类“org.jruby.RubyString”有 1,118,000 个字符串“”实例,仅空字符串使用的堆内存总量为 65mb,这对我来说很荒谬,因为它是内存的 15%由网络应用程序使用。空字符串只是许多存在此问题的字符串值的一个示例,如果我可以实习我计算出的所有 jruby 字符串,我可以节省大约 130mb。

我知道在 Java 中,每次创建一个字符串值时,它都会检查该值是否已存在于字符串池中,如果存在,则重用它。我想知道 Jruby 中是否有具有相同优化的选项?如果是这样,我该如何启用它?

Jruby 中的示例:

v1 = "a"
v2 = "a"
puts v1.object_id # => 3352
puts v2.object_id # => 3354

Java 示例:

String v1 = "a";
String v2 = "a";

System.out.println(v1.hashCode()); # => 97
System.out.println(v2.hashCode()); # => 97

最佳答案

我理解这背后的动机,但 JRuby 中确实没有这种“神奇”的开关......

从 Java 背景来看,节省字符串感觉很诱人,但您不能期望字符串在 JRuby 中的行为方式与它们在 Java 中的行为方式相同。首先,它们是完全不同的对象。我什至可以说 Ruby String 更像是 Java StringBuilder

周围有这么多 "" 实例当然是一种浪费,但是如果您提到的代码是第三方代码,那么您无能为力 - 除非您觉得自己像个猴子修补了很多。我会尝试确定大多数实例的来源并重构它们 - 但请记住在保存字符串时有一些“棘手”的部分,例如使用哈希:

{ 'foo' => 'bar' }

您可能会猜测这会创建 3 个对象,但您错了;它实际上创建了两个 'foo'。因为 String 是可变的(除非 frozen?)它dup 字符串和 freeze 当用作Hash 键(这是有充分理由的)。

另外请记住“智能地”重构 - 如果您不通过尝试降低分配实例的成本来减慢速度,请分析您正在更改的位。

关于java - 有没有办法让 Jruby 运行时实习所有字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10746737/

相关文章:

html - 将 CSS 和占位符文本应用于 Rails 登录表单

ruby - Rspec,将 spec 文件映射到被测 ruby​​ 文件

c# - 将泛型类型定义字符串从 C# 样式转换为 CLR 样式

python - 如何在Python中将字典键拆分为多个单独的键?

string - Go:将 rune (字符串)转换为二进制的字符串表示形式

java - 有没有办法用另一种类型的流动态生成和收集对象?

java - 总是在顶部窗口

java - GCP 语音转文本 - Java API 不起作用

java - 无需使用外部调试器即可轻松跟踪 java 程序中变量变化的方法

ruby - "newed"我类的类(class)名称