Hi folks,
Wie kann man den Speicherverbrauch einer Datenstruktur ermitteln. In Delphi gibt es z.B. einen sizeOf() Operator.
Hintergrund zur Frage. Ich habe einen Test mit JUnit für einen selbstgeschriebenen IdentCache der auch fix ist 100000 Einträg zufällig ermitteln und in die Cachestruktur dauert 1,8 Sekunden und ich dachte nehmen wir mal 1 Mill. und da kam de Heap. Nun ist die Speicherstruktur der Datencontainer theoretisch nicht 256m groß ???:L.
Ich habe einen Key String im Mittel 8 Zeichen+1 Prefix = 18 Byte
Ich habe einen Integer = 4 Byte.
Ich habe Containerdaten Integer "VALUE"+ 8 Zeichen für den Integer = (20) Byte
Ich habe die pointer in der TreeMap (BinaryTree) für die Suche nach Key
vermutlich left, adress, right of int 26 Byte;
Ich habe die pointer in der TreeMap (BinaryTree) für die Suche nach int dito 26 Byte;
Summe macht 22+52 = 74 Byte und wo ist das restliche Speicher?
Wie kann man ermitteln was die Kiste (JVM) wirklich verbraucht.
Danke und Bis denne huckfinn.
PS.:Ich hänge mal den Kode an
Und der IdentCacheEntry:
Wie kann man den Speicherverbrauch einer Datenstruktur ermitteln. In Delphi gibt es z.B. einen sizeOf() Operator.
Hintergrund zur Frage. Ich habe einen Test mit JUnit für einen selbstgeschriebenen IdentCache der auch fix ist 100000 Einträg zufällig ermitteln und in die Cachestruktur dauert 1,8 Sekunden und ich dachte nehmen wir mal 1 Mill. und da kam de Heap. Nun ist die Speicherstruktur der Datencontainer theoretisch nicht 256m groß ???:L.
Code:
public void testClear() {
int m=100000; // m= 1000000; HeapOverflow;
System.out.println("fill cache with "+m+" values and clear");
IdentCache cache = new IdentCache();
java.util.Random r = new Random(); int cnt=0;
for (int i = 0; i < m; i++) {
int random = r.nextInt();
if (cache.get(random)==null) {
cache.add("S"+Integer.toString(random),random,
new String("VALUE"+Integer.toString(random)));
cnt++;
}
}
System.out.println(cnt+" value in map.");
cache.clear();
System.gc();
assertTrue(" Cache ist leer!",cache.getEntries().size()==0);
}
Ich habe einen Key String im Mittel 8 Zeichen+1 Prefix = 18 Byte
Ich habe einen Integer = 4 Byte.
Ich habe Containerdaten Integer "VALUE"+ 8 Zeichen für den Integer = (20) Byte
Ich habe die pointer in der TreeMap (BinaryTree) für die Suche nach Key
vermutlich left, adress, right of int 26 Byte;
Ich habe die pointer in der TreeMap (BinaryTree) für die Suche nach int dito 26 Byte;
Summe macht 22+52 = 74 Byte und wo ist das restliche Speicher?
Wie kann man ermitteln was die Kiste (JVM) wirklich verbraucht.
Danke und Bis denne huckfinn.
PS.:Ich hänge mal den Kode an
Code:
public class IdentCache {
/** Die Token - Ident Relation */
TreeMap tokenMap = new TreeMap();
/** Die Ident - Token Relation */
TreeMap identMap = new TreeMap();
//___CONSTRUCT______________________________________________________________
/** Einfacher Konstruktor */
public IdentCache() { super(); }
//__________________________________________________________________________
/** Wertepaar hinzufügen
@param token StringToken
@param ident Indentifikatornummer */
public void add (String token, int ident)
throws IndexOutOfBoundsException { add(token, ident, null); }
//__________________________________________________________________________
/** Wertepaar mit Datenobjekt hinzufügen
@param token StringToken
@param ident Indentifikatornummer
@param object Datenobjekt */
public void add (String token, int ident, Object object)
throws IndexOutOfBoundsException {
IdentCacheEntry identEntry = (IdentCacheEntry)
identMap.get(new Integer(ident));
if (identEntry!=null) throw new IndexOutOfBoundsException(
"Doppelter Schlüssel '"+ident+"' !");
IdentCacheEntry entry = new IdentCacheEntry(token, ident, object);
tokenMap.put(token, entry ); identMap.put(new Integer(ident), entry);
}
//__________________________________________________________________________
/** Hole Eintrag über das Token
@param token StringToken */
public IdentCacheEntry get(String token) {
return (IdentCacheEntry) tokenMap.get(token);
}
//__________________________________________________________________________
/** Hole Eintrag über den Ident
@param ident Ident */
public IdentCacheEntry get(int ident) {
return (IdentCacheEntry) identMap.get(new Integer(ident));
}
//__________________________________________________________________________
/** Hole Ident über das Token
@param token StringToken */
public int getByToken(String token) throws IndexOutOfBoundsException {
IdentCacheEntry entry = (IdentCacheEntry) tokenMap.get(token);
if (entry==null) throw new IndexOutOfBoundsException(
"Unbekanntes Token '"+token+"' !");
return entry.getIdent();
}
//__________________________________________________________________________
/** Hole Token über den Ident
@param ident Ident */
public String getByIdent(int ident) throws IndexOutOfBoundsException {
IdentCacheEntry entry = (IdentCacheEntry) identMap.get(
new Integer(ident));
if (entry==null) throw new IndexOutOfBoundsException(
"Unbekannter Identifier '"+ident+"' !");
return entry.getToken();
}
//__________________________________________________________________________
/** Cache leeren */
public void clear() { tokenMap.clear(); identMap.clear(); }
//__________________________________________________________________________
/** Gebe alle Einträge als indiziertes Array heraus */
public ArrayList getEntries() {
return (new ArrayList(identMap.values()));
}
}
Und der IdentCacheEntry:
Code:
/** Element bestehend aus Ident, Tokennamen und Datenobjekt
* für die Konstruktion eines IdentCaches
* @author huckfinn alias Alexander Weidauer
*/
public class IdentCacheEntry {
//__________________________________________________________________________
/** Das Klartexttoken z.B. ein XML-Tag */
private String token = "null";
//__________________________________________________________________________
/** Die Ident Variable als ganze Zahl */
private int ident = -1;
//__________________________________________________________________________
/** Datenobjekt */
private Object data = null;
//__________________________________________________________________________
/** erweiterter Konstruktor mit Tokenstring und Ident */
public IdentCacheEntry(String token, int ident) {
this.token = token; this.ident = ident; }
//__________________________________________________________________________
/** erweiterter Konstruktor mit Tokenstring, Ident und Datenobjekt */
public IdentCacheEntry(String token, int ident, Object data) {
this.token = token; this.ident = ident; this.data = data; }
//__________________________________________________________________________
/** Zugriff auf Feld token lesend */
public String getToken() { return token;}
//__________________________________________________________________________
/** Zugriff auf Feld token schreibend
@param token neuer Wert des Namenstoken */
public void setToken(String token) { this.token = token; }
//__________________________________________________________________________
/** Zugriff auf Feld data lesend */
public Object getObject() { return data;}
//__________________________________________________________________________
/** Zugriff auf Feld data schreibend
@param data neues Datenobjekt */
public void setObject(String data) { this.data = data; }
//__________________________________________________________________________
/** Zugriff auf Feld ident lesend */
public int getIdent() { return ident; }
//__________________________________________________________________________
/** Zugriff auf Feld ident schreibend
@param ident neues Wert des Ident */
public void setIdent(int ident) { this.ident = ident; }
}