Ich habe die Zeit Kosten von Unmarshalling XML zu Objekten mit Jaxb2 mit einer großen (1,7 MB) XML-Payload mit etwas langen (48 Zeichen) Tag-Namen gemessen. Ich beobachtete via JProfiler im Sampling-Modus, dass String-Interning-Arbeit einen festen Teil der Zeit verbrachte.Das Deaktivieren des String-Internings innerhalb von Jaxb2 beschleunigt das Zurückmarshalieren von einem Fastinfoset-Stream. Warum ist es so schwer zu deaktivieren?
Ich habe einige Nachforschungen gemacht und festgestellt, dass Jaxb in einem Modus betrieben werden kann, in dem es keine Strings sperrt. Meine Theorie war, dass in einigen Fällen die Nicht-Internierung von Zeichenketten beim Unmarshalling die Leistung auf Kosten der Verwendung von mehr Heap-Speicher verbessern konnte, da nicht jeder Tag-Name-String während des Interning-Prozesses durchsucht werden musste.
Die Methode, die ich verwendet, um jaxb der Internierung Verhalten unterdrücken war auf dem Fastinfoset „StAXDocumentParser“, um den „org.codehaus.stax2.internNames“ und „org.codehaus.stax2.internNsUris“ Eigenschaften (die XMLStreamReader implementiert). Es ist mir nicht 100% klar, warum Sie diese auf "true" setzen müssen, um zu verhindern, dass Jaxb Strings interniert, aber so funktioniert es.
Diese JUnit getriebene Tests sind, was ich, dass das Deaktivieren jaxb String interning Verhalten einen großen Unterschied in der Leistung macht den Abschluss verwendet:
https://github.com/gjd6640/fastinfoset-performance-evaluation
Also meine Frage ist mehrteilig:
1) Missverstehe ich etwas Wichtiges und sollte ich nicht versuchen, Jaxbs String-Interning-Verhalten zu deaktivieren?
2) Gibt es eine bessere Möglichkeit, Jaxb nicht zu internen Strings zu leiten? Mit der Klasse "StAXManager" können Sie diese Woodstox-orientierten Eigenschaften nicht festlegen. Für diesen Test habe ich den StAXManager wie unten gezeigt erweitert, um das Problem zu umgehen. Dies ist ein Hack, den ich in der Produktion nicht verwenden möchte. Ich vermute, dass die Idee hier ist, dass, wenn Jaxb von einem Woodstox-Stream entpackt wird, er sieht, ob Woodstox bereits interniert und wenn "Ja" reagiert, reagiert Jaxb, indem er diesen Schritt des Prozesses deaktiviert. Ich betrüge, indem ich diese Logik in der Jaxb-Bibliothek piggybacke, also möchte ich einen besseren Weg, dies zu tun.
package com.sun.xml.fastinfoset.stax;
public class JaxbStringInternSuppressionStaxManager extends StAXManager {
public JaxbStringInternSuppressionStaxManager() {
// Add to the allowable list of feature names so that the user may set these "StAXInputFactory" properties
super.features.put("org.codehaus.stax2.internNames", null);
super.features.put("org.codehaus.stax2.internNsUris", null);
}
}
Update:
Wie üblich, "Eine Frage gut gestellt ist halb beantwortet". Ich habe gerade beim Verfassen dieser Frage bemerkt, dass "com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector" überprüft, ob die Klasse "com.sun.xml. internal .rastinfoset.stax.StAXDocumentParser" "ist vom verwendeten XMLStreamReader zuweisbar und aktiviert String-Interning nicht. In meinem Fall ist mein Stream-Objekt ein "com.sun.xml.fastinfoset.stax.StAXDocumentParser", so dass das Internieren nicht deaktiviert wird. Nun stellt sich die Frage: "Warum tut es das nur für den internen Geschmack der Fastinfoset-Bibliothek?" Vielleicht finde ich die Antwort, indem ich this post sorgfältig lese.
Wenn es ein besseres Forum für diese Art von Frage gibt, wie zum Beispiel eine aktive Entwickler-Benutzergruppe, teilen Sie bitte diese Informationen mit und ich werde sie über diesen Beitrag verlinken, damit die richtigen Leute diese Frage sehen.
Addendum: Ich benutze JDK: 64-Bit jdk1.8.0_121, die scheint, bündeln Klassen von Oracle "com.sun.xml.bind: jaxb-impl" Bibliothek Version "2.1-b02-fcs". –