# Größe eine Variablen in Bytes?



## tuxedo (30. Jul 2007)

Gibts ne Möglichkeit dass man sich die Bytes, die eine Variable im Speicher belegt, ausgeben lassen kann?

- Alex


----------



## SlaterB (30. Jul 2007)

du kannst dir die aktuelle Speicherbelegung anschauen:

```
Runtime runtime = Runtime.getRuntime();
        long max = runtime.maxMemory();
        long free = runtime.freeMemory();
        long total = runtime.totalMemory();
```
wenn du das einmal machst,
ein Array der Länge 100.000 vom gewüschten Typ anlegst
und nochmal den Speicher anschaust,
dann dürften recht genau x00.000 Bytes mehr belegt sein


----------



## jPat (30. Jul 2007)

Es gibt aber ein tool jconsole.exe. damit kannst du deine Programme ganz gut überwachen .... Evtl findes du dort etwas.


----------



## FelixB (30. Jul 2007)

kannst du etwas genauer sagen, worum es dir geht?


----------



## tuxedo (30. Jul 2007)

Ach, nix wildes:

Für meinen JDBC-Treiber (http://jpmdbc.dev.java.net) würd ich gerne ne Art Benchmark-Test machen, und da wäre es interessant zu wissen wie viel Speicher meine im ResultSet verwendete Daten-Variable braucht. Im Endeffekt kann ich ja auch die Bytes lesen die ich aus dem Stream gelesen hab. Dachte halt es gäbe was um eine Varibale exakt zu bestimmen.

- Alex


----------



## Wildcard (30. Jul 2007)

alex0801 hat gesagt.:
			
		

> Dachte halt es gäbe was um eine Varibale exakt zu bestimmen.


Dafür ist erst mal die Metrik interessant.
Nimm an ein Objekt x braucht 20 byte.
Ein zweites Objekt mit gleichem Inhalt braucht nun aber nur noch 10 byte weil sie sich Resource Teilen.
Welcher der beiden Werte ist der echte Speicherverbrauch?
Zählen Referenzen auf enthaltene Objekte mit?
Wenn ja, nur die Größe der Referenz, oder auch deren Größe?
Was passiert mit Objekten nach dem Fliegengewicht Muster?
Du siehst, so einfach ist die Sache nicht.


----------



## tuxedo (30. Jul 2007)

Naja, ich habs halt in Bezug auf ne HashMap gesehen, ohne weitere verlinkung oder so. Wenn ich sowas serialisiere und irgendwo speichere hab ich ja auch ne bestimmte Größe.

- Alex


----------



## Wildcard (30. Jul 2007)

Ja, du bekommst *eine* Größe. Ob es die ist, die für dich interessant ist, kannst nur du selbst beantworten.


----------



## tuxedo (30. Jul 2007)

Naja, die Größe repräsentiert irgendwie die Größe der Daten in meiner HashMap. Ob da jetzt ein wenig "overhead" dabei ist oder nicht, spielt für mich eine untergeordnete Rolle. Mir gehts nur dum eine Größe zu finden die reproduzierbar ist und die ich vergleichen kann.


----------



## Wildcard (30. Jul 2007)

Du spachst doch selbst schon die serialisierung an....


----------



## tuxedo (30. Jul 2007)

jepp, serialisierung wäre das eine. die andere Lösung, für meinen Fall, wäre das mitzählen der empfangenen bytes. 

Aber wenns halt schon sowas gegeben hätte wie z.B. (frei erfunden).


```
public int System.getMemoryUsage(Object o)
```

oder so, wäre das halt "cooler" gewesen.


----------



## Gast (30. Jul 2007)

naja das kannst du dir ja selber ausrechnen. Die größen der primitiven datentypen sind bekannt (google) also int z.B. 32bit und das kannst du dir ja dann einfach zusammen rechnen, rekursiv wenn du möchtest


----------



## tuxedo (30. Jul 2007)

Naja, ich hab "komplexe/verschachtelte" HashMaps mit byte[]'s drin... da müsst ich erst alles abklappern ums zusammen zu rechnen. Aber egal. ich hab ja genug lösungsmöglichkeiten.

- Alex


----------



## Wildcard (30. Jul 2007)

alex0801 hat gesagt.:
			
		

> ```
> public int System.getMemoryUsage(Object o)
> ```
> 
> oder so, wäre das halt "cooler" gewesen.


Und ich habe dir bereits erklärt warum es so etwas nicht gibt. Weil sich jeder auf eine andere Metrik bezieht und eine allgemeine Methode daher Unsinn ist.


----------



## SlaterB (30. Jul 2007)

es gibt doch nur eine Metrik, die kinderleicht als die entscheidene zu erkennen und zu berechnen ist: 
der aktuelle Speicherverbrauch des Objekes,

so wie wenn man es zu diesem Zeitpunkt serialisieren würde,
so wie der Garbage-Collector sich alles anschaut,

das ist präzise, nichts anderes könnte man von einer solchen Operation zu einem aktuell vorhandenen Objekt zur Laufzeit erwarten

gerne kann man sich mit Spezialfällen rumärgern, z.B. Objekte die auf System- oder AWT-Variablen verweisen und dann transitiv den halben Speicher mitreferenzieren,
für die wäre das Ergebnis dann eben unbrauchbar, für einfache eigene Objekte aber umso nützlicher

dass man simple Referenzen auf gleiche Objekte usw. bedenken muss, ist ja kein Nachteil, 
das muss man etwa bei  runtime.freeMemory() genauso


----------



## Wildcard (30. Jul 2007)

SlaterB hat gesagt.:
			
		

> es gibt doch nur eine Metrik, die kinderleicht als die entscheidene zu erkennen und zu berechnen ist:
> der aktuelle Speicherverbrauch des Objekes,


Um hier nicht weiter abzuschweifen nehmen wir ein ganz einfaches Beispiel.
Mein Objekt ist eine Instanz dieser Klasse:

```
class Foo{
   public String bar;
}
```
Wie ist der Speicherverbrauch zu berechnen?


----------



## Gast (30. Jul 2007)

Speicherverbrauch = Referenz auf String + Größe von String Objekt

und die Größe vom String kann man dann rekursiv wieder auflösen bis man bei den primitiven datentypen angekommen ist


----------



## Wildcard (30. Jul 2007)

Gast hat gesagt.:
			
		

> Speicherverbrauch = Referenz auf String + Größe von String Objekt
> 
> und die Größe vom String kann man dann rekursiv wieder auflösen bis man bei den primitiven datentypen angekommen ist


String instanzen werden in einem Pool gesammelt und unter den Objekten verteilt. Der selbe String (und substrings davon) belasten den Speicher also nur einmal.


----------



## SlaterB (31. Jul 2007)

> Wie ist der Speicherverbrauch zu berechnen?

Arbeitsspeicher, locker und leicht, jedes einzelne Bit ist genau definiert..

> Der selbe String (und substrings davon) belasten den Speicher also nur einmal.

was ja bei jedem Objekt der eigenen Klasse genauso ist, völlig normaler Vorgang,
bei String gibts natürlich die Besonderheit, dass die vom System zusammengesetzt werden und z.T. doppelt sind,
das muss man wissen, und hoffentlich in seinem Programm beachten, ändert aber an der Eindeutigkeit nichts

es sei denn, es findet irgendwann mal eine Optimierung statt, bei der gleiche Strings zusammengelegt werden?
wird z.B. bei der Serialisierung was besonderes gemacht, vielleicht auch andersrum: mehrere Referenzen auf gleichen String einzeln gespeichert?
(in separaten Dateien eh für alle Objekte, aber in einer Datei)

wie auch immer es geregelt ist, es gibt eine eindeutige vom System vorgegebene aktuelle Größe


----------



## tuxedo (31. Jul 2007)

@Wildcard

Naja, man kann die ganze Sache auch zu feingranular betrachten... 

@SlaterB

Du hasts getroffen (schon in nem vorherigen Post von dir). Genau sowas hab ich mir vorgestellt. Aber ne einfache Methode du man einfach aufrufen kann gibts da nicht, oder etwa doch?

Klar, ich könnte weiter an meiner serialisierung festhalten. Aber das geht ja unter Umständen wieder zu lasten der Laufzeit. Wenn dem GC und Co. solche Sachen bereits bekannt sind und man die Abfragen könnte, wäre das "schick" 

-Alex


----------



## Wildcard (31. Jul 2007)

SlaterB hat gesagt.:
			
		

> wie auch immer es geregelt ist, es gibt eine eindeutige vom System vorgegebene aktuelle Größe


Nein, genau die gibt es nicht. Es gibt mehrere Einzelgrößen die je nach Metrik zusammengesetzt werden müssen.
Was du als die einzig richtige Metrik verkaufst, kann für meinen Anwendungsfall totaler Unsinn sein.
Ich sage ja nicht das es unmöglich ist solche Größen zu messen, nur die Parameter muss jeder eben selbst festlegen.


----------



## SlaterB (31. Jul 2007)

nun, was alles Unsinn ist muss jeder selber wissen,

da es aber eben nur einen einzelnen Arbeitsspeicher zu verwalten gibt,
ist die Belegung dieses Arbeitsspeichers zum einen eine äußerst sinnvolle Information und zum anderen eindeutig zu berechnen,
(zum dritten: gibts zum Teil schon, siehe Runtime.getFreeMemory())

wenn das nicht zwei Killerargumente für eine derartige Operation sind, dann weiß ich auch nicht 

ich widerspreche dir ja von Anfang an nicht, dass verschiedene Größen denkbar sind, 
ich sage nur, dass es eine eindeutige vorgegebe, sozusagen kanonische, REALE Größe gibt, 
die man natürlich unter den vorgegebenen Randbedingungen interpretieren muss


----------



## Wildcard (31. Jul 2007)

SlaterB hat gesagt.:
			
		

> da es aber eben nur einen einzelnen Arbeitsspeicher zu verwalten gibt,
> ist die Belegung dieses Arbeitsspeichers zum einen eine äußerst sinnvolle Information und zum anderen eindeutig zu berechnen,
> (zum dritten: gibts zum Teil schon, siehe Runtime.getFreeMemory())


Richtig, Runtime.getFreeMemory gibt es (hier ist es auch eine eindeutige Sache, und richtig, die Belegung des Arbeitsspeichers lässt sich eindeutig bestimmen, und richtig, es ist eine nützliche Information.
Aber:
Die Menge an Speicher die *ein* Objekt im Arbeitsspeicher belegt, steht auf einem ganz anderen Blatt und lässt sich eben nicht mit allgemeingültigen Kriterien erschlagen.


----------

