T
tuxedo
Gast
Hallo,
hab eine WeakHashMap die mir als eine Art Cache dient:
[HIGHLIGHT="Java"]private static WeakHashMap<Method, Long> methodHashs = new WeakHashMap<Method, Long>();[/HIGHLIGHT]
Ich benutze diese, um anhand einer Methode schnell den dazugehörigen "Hash" zu erhalten. Ist der Hash noch nicht in der Mapp enthalten, so berechne ich ihn und trage ihn in die Liste ein.
Bisher sieht die Methode so aus:
[HIGHLIGHT="Java"]public static long computeMethodHash(Method m) {
if (methodHashs.containsKey(m)) {
synchronized (methodHashs) {
logger.trace("Got hash from map. map contains {} entries.", methodHashs.size());
return methodHashs.get(m); // <--- Hier hagelts hin und wieder NPEs
}
} else {
// berechne hash ...
// ....
// ....
synchronized (methodHashs) {
methodHashs.put(m, hash);
logger.trace("computed new hash. map now contains {} entries.", methodHashs.size());
}
return hash;
}
}[/HIGHLIGHT]
In den meisten Fällen funktioniert der Code, da zwischen "containsKey()" und "get()" die Map nicht aufgeräumt wird. Aber hin und wieder hagelts da halt auch NullpointerExceptions, weil die Map sich zwischen den beiden Aufrufen schon geändert hat, sprich der GC den Eintrag unter umständen schon entsorgt hat.
Den Cache hab ich überhaupt erst eingeführt, weil das errechnen des Hashes etwas aufwendig ist und ich diesen Rechenaufwand gerne wo möglich vermeiden möchte. Es reicht ja wenn ich den Hash einmal berechne und ihn dann cache.
Aber zurück zum Problem. Da ich wie gesagt seehr oft den Hash zur Methode haben möchte (im Worst-Case etliche tausend mal pro Sekunde), und das möglichst effizient, weiß ich (noch) nicht wie man das am performantesten regelt.
Eine Idee wäre statt zu Fragen ob die Methode in der Map bekannt ist, den Hash einfach rausholen. Da primitive aber nicht "null" sein können, müsste ich das in ein Long Objekt oder so casten und schauen ob das null ist. Und erst wenn dieses NICHT null ist, den Wert des Long-Objekts zurückgeben. Ist das Long-Objekt null, so errechne ich den Hash.
Hab aber :rtfm: dass das casten, und vor allem die Nutzung von den Wrapper-Klassen für die primitiven Datentypen nicht so performant sein soll. Da ich aber für diesen Ansatz _jedesmal_ ein Wrqapper-Objekt bräuchte, wäre das wohl ein neuer Flaschenhals in meiner Anwendung :shock:
Hab auch versucht den ganzen Mehodenbody auf das Map-Objekt zu synchronisieren, aber geholfen hat's komischerweise nicht :autsch:
Letztendlich kann man die Frage wohl so formulieren:
Wie benutzt man eine WeakHashMap richtig und vor allem performant, so dass man zuverlässig keine NPE bekommt wenn man Elemente daraus haben möchte die eigtl. primitive Datentypen sind, und diese ggf. schon abgeräumt wurden ???:L
Gruß
Alex
hab eine WeakHashMap die mir als eine Art Cache dient:
[HIGHLIGHT="Java"]private static WeakHashMap<Method, Long> methodHashs = new WeakHashMap<Method, Long>();[/HIGHLIGHT]
Ich benutze diese, um anhand einer Methode schnell den dazugehörigen "Hash" zu erhalten. Ist der Hash noch nicht in der Mapp enthalten, so berechne ich ihn und trage ihn in die Liste ein.
Bisher sieht die Methode so aus:
[HIGHLIGHT="Java"]public static long computeMethodHash(Method m) {
if (methodHashs.containsKey(m)) {
synchronized (methodHashs) {
logger.trace("Got hash from map. map contains {} entries.", methodHashs.size());
return methodHashs.get(m); // <--- Hier hagelts hin und wieder NPEs
}
} else {
// berechne hash ...
// ....
// ....
synchronized (methodHashs) {
methodHashs.put(m, hash);
logger.trace("computed new hash. map now contains {} entries.", methodHashs.size());
}
return hash;
}
}[/HIGHLIGHT]
In den meisten Fällen funktioniert der Code, da zwischen "containsKey()" und "get()" die Map nicht aufgeräumt wird. Aber hin und wieder hagelts da halt auch NullpointerExceptions, weil die Map sich zwischen den beiden Aufrufen schon geändert hat, sprich der GC den Eintrag unter umständen schon entsorgt hat.
Den Cache hab ich überhaupt erst eingeführt, weil das errechnen des Hashes etwas aufwendig ist und ich diesen Rechenaufwand gerne wo möglich vermeiden möchte. Es reicht ja wenn ich den Hash einmal berechne und ihn dann cache.
Aber zurück zum Problem. Da ich wie gesagt seehr oft den Hash zur Methode haben möchte (im Worst-Case etliche tausend mal pro Sekunde), und das möglichst effizient, weiß ich (noch) nicht wie man das am performantesten regelt.
Eine Idee wäre statt zu Fragen ob die Methode in der Map bekannt ist, den Hash einfach rausholen. Da primitive aber nicht "null" sein können, müsste ich das in ein Long Objekt oder so casten und schauen ob das null ist. Und erst wenn dieses NICHT null ist, den Wert des Long-Objekts zurückgeben. Ist das Long-Objekt null, so errechne ich den Hash.
Hab aber :rtfm: dass das casten, und vor allem die Nutzung von den Wrapper-Klassen für die primitiven Datentypen nicht so performant sein soll. Da ich aber für diesen Ansatz _jedesmal_ ein Wrqapper-Objekt bräuchte, wäre das wohl ein neuer Flaschenhals in meiner Anwendung :shock:
Hab auch versucht den ganzen Mehodenbody auf das Map-Objekt zu synchronisieren, aber geholfen hat's komischerweise nicht :autsch:
Letztendlich kann man die Frage wohl so formulieren:
Wie benutzt man eine WeakHashMap richtig und vor allem performant, so dass man zuverlässig keine NPE bekommt wenn man Elemente daraus haben möchte die eigtl. primitive Datentypen sind, und diese ggf. schon abgeräumt wurden ???:L
Gruß
Alex