Gibt es eine Möglichkeit, die Jruby-Laufzeit intern alle Strings intern zu machen?

8

Wir haben eine java / jruby-Webapp unter Tomcat laufen, und ich habe die Anzahl der Objekte und Speicherverbrauch von der App zur Laufzeit analysiert. Ich habe bemerkt, nach dem Start der Klasse "org.jruby.RubyString" hatte 1.118.000 Instanzen der Zeichenfolge "", die gesamte Menge an Heap-Speicher von leeren Strings allein verwendet wird 65mb, das ist mir lächerlich, weil es 15% des Speichers ist Wird von der Webanwendung verwendet. Die leere Zeichenfolge ist nur ein Beispiel für viele String-Werte mit diesem Problem, wenn ich alle jruby-Strings internieren kann, die ich ausgearbeitet habe, könnte ich etwa 130 MB sparen.

Ich weiß in Java, dass jedes Mal, wenn ein Zeichenfolgenwert erstellt wird, überprüft wird, ob der Wert bereits im Zeichenfolgenpool vorhanden ist, und ihn erneut verwenden, falls dies der Fall ist. Ich frage mich, ob es eine Option in Jruby gibt, die dieselbe Optimierung hat? Wenn ja, wie aktiviere ich es?

Beispiel in Jruby:

%Vor%

Beispiel in Java:

%Vor%     
Chiwai Chan 24.05.2012, 23:39
quelle

4 Antworten

5

Ich verstehe die Motivation dahinter, aber es gibt wirklich keinen solchen "magischen" Schalter in JRuby ...

Von einem Java-Hintergrund fühlt es sich an, in Strings zu speichern, aber Sie können nicht erwarten, dass Strings sich in JRuby genauso verhalten wie in Java. Vor allem sind sie ein ganz anderes Objekt. Ich würde so weit gehen zu sagen, dass ein Ruby String eher ein Java StringBuilder ist.

Es ist sicherlich eine Verschwendung, so viele "" Instanzen herumliegen zu haben, aber wenn dieser Code, wie du es erwähnst, Code von Drittanbietern ist, kannst du nicht viel dagegen tun - es sei denn, du fühlst dich wie ein Affe. Ich würde versuchen, die Orte zu identifizieren, aus denen die meisten Instanzen kommen, und sie umgestalten - aber denken Sie daran, dass es einige "knifflige" Teile gibt, um Saiten zu speichern, z. mit Hash :

%Vor%

Du würdest vermuten, dass dies 3 Objekte erzeugt, aber du liegst falsch; es erstellt tatsächlich zwei der 'foo' . Da ein String änderbar ist (außer frozen? ), ist es dup s die Zeichenfolge und freeze s, wenn es als Hash Schlüssel verwendet wird (und dafür gibt es einen guten Grund).

Denken Sie auch daran, "intelligent" umzufunktionieren - profilieren Sie die Bits, die Sie ändern, wenn Sie die Dinge nicht verlangsamen, indem Sie versuchen, bei zugewiesenen Instanzen billig zu werden.

    
kares 29.05.2012 12:41
quelle
2
%Vor%

Erstellt nur ein Objekt in Ruby, nicht drei.

%Vor%

Bevor ich etwas so drastisches wie das Internieren aller Saiten tue, würde ich mich mit anderen Tomcat-Benutzern besprechen, ob dies der beste Weg ist, mit diesem Problem umzugehen. Ich benutze weder Tomcat noch JRuby, aber ich vermute stark, dass dies nicht der beste Ansatz ist.

Bearbeiten Wenn jedes Objekt, das aus einem "a" erstellt wurde, dasselbe Objekt ist, würde das Ändern eines dieser Objekte alle anderen Zeichenfolgen ändern. Das wäre ein Nebeneffekt Albtraum.

    
Andrew Grimm 27.05.2012 23:21
quelle
1

Die einzige Möglichkeit, einen String in JRuby zu internieren, besteht darin, to_sym oder intern (sie alias einander) aufzurufen und sie zu Symbolen zu machen - was, wie du erwähnt hast, nicht wirklich für Drittanbieter hilfreich ist Edelsteine. Soweit ich weiß, gibt es keinen anderen Weg.

Dies entspricht dem MRI-Verhalten:

%Vor%     
Sébastien Le Callonnec 28.05.2012 06:44
quelle
0

Dies ist jetzt das Standardverhalten in JRuby. Ab Version 9.1 geben alle eingefrorenen String-Literale (z. B. 'hello'.freeze ) dieselbe Instanz zurück, und dasselbe gilt für Literal-Strings, die als Hash-Schlüssel verwendet werden (z. B. stuff['thing'] ) und einige andere Fälle. Siehe JRuby-Problem # 3491 .

Wenn Sie alle Zeichenkettenliterale aggressiv einfrieren möchten, können Sie sowohl JRuby (9.1+) als auch Ruby (2.3+) mit --enable-frozen-string-literal ausführen. Bereiten Sie sich jedoch darauf vor, dass Dinge unterbrochen werden, da die meisten Elemente annehmen, dass Zeichenketten änderbar sind.

    
Theo 19.06.2017 18:57
quelle

Tags und Links