Ich bin auf der Suche nach einer Möglichkeit, String
aus einem byte[]
in Java mit so wenig Müll wie möglich zu deserialisieren. Da ich meinen eigenen Serialisierer und Deserialisierer erstelle, habe ich die völlige Freiheit, irgendeine Lösung auf der Serverseite (d. H. Beim Serialisieren von Daten) und auf der Clientseite (d. H. Beim Deinserialisieren von Daten) zu implementieren.Zero-Müll große String-Deserialisierung in Java, Humongous Objekt Ausgabe
I haben, um effizient Serialisieren ein String
ohne anfallenden Müll jede Overhead durch Iterieren durch die String's
Zeichen verwaltet (String.charAt(i)
) und Umwandeln jedes char
(16-Bit-Wert) 8-Bit-Wert 2x. Es gibt eine nette Debatte über diese here. Eine Alternative ist die Verwendung von Reflection zum direkten Zugriff auf String's
char[]
, aber dies liegt außerhalb des Bereichs des Problems.
Allerdings scheint es mir unmöglich, die byte[]
deserialisieren, ohne die char[]
zweimal zu schaffen, die, na ja, seltsam scheint.
Das Verfahren:
char[]
erstellen- Iterate durch
byte[]
und füllen Sie daschar[]
- String erstellen mit
String(char[])
Konstruktor
Wegen String
Unveränderlichkeit Regeln Java, der Konstruktor Kopiert den char [] und erstellt 2x GC Overhead. Ich kann immer Mechanismen verwenden, um dies zu umgehen (unsichere String
Zuweisung + Reflexion, um die char[]
Instanz zu setzen), aber ich wollte nur fragen, ob es irgendwelche Auswirkungen auf diese andere als ich brechen jede Konvention auf String's
Unveränderlichkeit.
Natürlich wäre die weiseste Antwort darauf "Komm schon, hör auf damit und vertraue auf GC, das Original char[]
wird extrem kurzlebig und G1 wird es momentan loswerden", was eigentlich Sinn macht , , wenn die char[]
kleiner ist als 1/2 der G1-Regionsgröße. Wenn es größer ist, wird char [] direkt als ein menschliches Objekt zugewiesen (d. H. Automatisch außerhalb der Region von G1 verbreitet). Solche Objekte sind extrem schwer effizient in G1 zu sammeln. Deshalb ist jede Zuweisung wichtig.
Irgendwelche Ideen, wie man das Problem angeht?
Vielen Dank.
Haben Sie in Betracht gezogen, einfach nicht mit Strings zu arbeiten und nur die Rohbyte-Daten zu serialisieren und Zeichensatzkonvertierungen an Teilabschnitten durchzuführen, wenn es absolut notwendig ist? – the8472
Ich habe. Meine Idee war es, eine neue Klasse 'MutableString' zu erstellen, und eine Menge von traditionell mülllastigen Operationen über ihr zu implementieren (zum Beispiel Fastpath 'String' Split) und dann eine Methode' toString (from, to) 'zu erstellen eine "view" -Instanz, die vom Typ "String" ist. Das könnte ich machen. Dies würde jedoch erfordern, unsere Anwendung komplett zu überarbeiten und "MutableString" überall zu verwenden. Es ist eine nette Idee, aber ich wollte zuerst Alternativen erkunden. – SergioTCG
Wissen Sie, dass all diese Dinge bereits existieren? Es gibt 'CharBuffer' und' StringBuilder', beide sind eine Art veränderbarer 'String' (es sei denn, Sie haben eine unveränderliche Ansicht erstellt), es gibt Methoden zum Erstellen leichter Untersequenzen von ihnen und sie implementieren alle' CharSequence', die 'Schnittstelle ', auf dem das Regex-Paket, das tatsächlich die' Split'-Operation implementiert, arbeitet. Und während * aussieht * wird der Zeicheninhalt immer kopiert, wenn zwischen 'String's,' CharBuffer's und 'StringBuilder's beim Betrachten des Quellcodes umgeschaltet wird. HotSpot hat spezielle Optimierungen für sie ... – Holger