Wie groß ist eigentlich ein HashMap?

fatfox

Bekanntes Mitglied
Hallo alle,

Ich möchte 36 millionen Einträge in eine ArrayList von HashMap(c.a. 15,000 Stück) eingeben. Aber Warum nach ein paar Millionen Einträge Eingaben ist mein Computer unglaublich langsam geworden?

Meine <Key> type ist Short und <Value> type ist Float. Ich benutze put(key, value) Funktion.

Ich denke: 36,000,000 × (2 + 4) ÷1024÷1024 = 205 MB, also 205MB Ram muss reichen, aber warum im Real ist es anders?


Vielen Dank!
 
Zuletzt bearbeitet:

faetzminator

Gesperrter Benutzer
Weil du da keine primitiven Datentypen nutzen kannst. Mit Millionen von Referenzen hat man irgendwann den Speicher voll. Schreib dir etwas mit Arrays o.ä., bei denen du primitive Datentypen nutzen kannst.
 
S

SlaterB

Gast
wenn du es genau wissen willst dann bietet Runtime.getRuntime() Methoden zum Java-Speicher,
teste zunächst z.B. ein short[] im Vergleich zu einem Short[]

selbst wenn man Objekte verwenden muss, kann es sich schon lohnen, die 30.000 oder 60.000 möglichen Werte zu cachen und mehrfach zu verwenden,
jedes Objekt ist eine Referenz von 4 Byte + dem Objekt selber, ein Short vielleicht 20 Byte oder so, testen

Langsamheit ist auch eher 100% CPU-Last als irgendwas mit Speicher?
 

fatfox

Bekanntes Mitglied
Danke alle! Der "Short" ist so groß habe ich gar nicht gewusst! ( ° △ °|||)︴

To Landei: der Trove sieht sehr sehr gut aus, aber irgendwie weiß ich gar nicht, wo und wie ich das anfangan soll....Gibt es irgendwo ein Tutorial?
 
Zuletzt bearbeitet:

Landei

Top Contributor
Schau einfach in die JavaDoc. Wenn du z.B. eine Map von short nach float brauchst, müsste das TShortFloatHashMap sein. Das ist dann - zumindest von der Bedienung her - eine 1:1 "Übersetzung" des Map-Interfaces in Primitive, also überall wo bei Map<K,V> ein K steht, steht hier short, und anstatt V eben float, z.B. wird aus [c]V get(K key)[/c] ein [c]float get(short key)[/c].
 

fatfox

Bekanntes Mitglied
Schau einfach in die JavaDoc. Wenn du z.B. eine Map von short nach float brauchst, müsste das TShortFloatHashMap sein. Das ist dann - zumindest von der Bedienung her - eine 1:1 "Übersetzung" des Map-Interfaces in Primitive, also überall wo bei Map<K,V> ein K steht, steht hier short, und anstatt V eben float, z.B. wird aus [c]V get(K key)[/c] ein [c]float get(short key)[/c].

Cool!!! Der TShortFloatHashMap funktioniert!!! und ich kann jetzt alle 36 millionen Einträge eingeben.

Aber es ist einbisschen komisch, weil die TShortFloatHashMap trotzdem c.a. 1.4 GB Ram braucht.

Nach der Hinweise von SlaterB ist der Object so groß:
jedes Objekt ist eine Referenz von 4 Byte + dem Objekt selber

[36000000 × ( 2 + 4 ) + ( 15000 × 4 ) ] ÷ 1024 ÷ 1024 + 15000= 206 MB (short ist 2 byte, float ist 4 byte; Referenz 4 byte, ich habe 15000 Stücke TShortFloatHashMaps)

Warum???
 
Zuletzt bearbeitet:
S

SlaterB

Gast
die Map-Objekte an sich sind bisschen größer, haben noch Attribute, brauchen als Objekt initial vielleicht noch etwas mehr Bytes,
jedes der Array-Objekte vielleicht genaue auch ein paar Bytes, aber in der kleinen Anzahl nicht so entscheidend,
großzügig kann man da 15.000 x 100 rechnen und ist immer noch im einstelligen MB-Bereich,

etwas interessanter ist, dass dem SourceCode nach
Java > Open Source Codes > gnu > trove > TPrimitiveHash _ Java API By Example, From Geeks To Geeks.
mindestens noch ein drittes Array für alle Einträge besteht, allerdings mit byte, also vielleicht auch nur 36 MB zusätzlich,

am ehesten richtig Verbrauch könnte die Tatsache schaffen, dass die Maps ihren Platz im Voraus anlegen und das nicht bei jedem Einfügen neu machen wollen,
wenn eine Map voll oder ziemlich voll ist können Arrays mit bis zur doppelten der vorherigen Größe angelegt werden

falls du da nicht optimiert hast sind da im ungünstigsten Fall auch 100 MB unnötig reserviert

----

eine richtige Erklärung ist all das aber nicht, eher vermute ich Probleme beim restlichen Programm,
wie liest du die 36 Millionen Werte ein, sind die vielleicht noch irgendwo im Speicher vorhanden, gar im ungünstigen String-Format?
ich kann morgen vielleicht ein kleines Testprogramm schreiben, mit 36 Mio. Zufallswerten den Platz messen
bzw. im kleineren Maßstab
 

fatfox

Bekanntes Mitglied
eine richtige Erklärung ist all das aber nicht, eher vermute ich Probleme beim restlichen Programm,
wie liest du die 36 Millionen Werte ein, sind die vielleicht noch irgendwo im Speicher vorhanden, gar im ungünstigen String-Format?
ich kann morgen vielleicht ein kleines Testprogramm schreiben, mit 36 Mio. Zufallswerten den Platz messen
bzw. im kleineren Maßstab

Hi SlaterB, das ist echt nett von dir!!! :D Danke!!!

Ich habe am Anfang mit Augen gemessen, wie groß ist der Objekt. (Also gucke der System Monitor von Ubungtu ◑ˍ◐ ) Das ist c.a. 1.4 GB.
Dann habe ich noch mal mit deiner Methode [c]Runtime.getRuntime[/c] das Objekt gemessen:
Java:
t1 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
.............
t2 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
System.out.println( ( t1-t2 ) / 1024 / 1024 );
Das ist nur c.a.900 MB, wo sind die 500MB???? ╮(╯▽╰)╭

---------------------------

Ich habe das Objekt auch serialization gemacht. Die Datei ist nur c.a. 210MB.

Bei Lesen kostet der Computer c.a. 900 MB Speichern(per ◑ˍ◐), aber nach deiner Methode kostet c.a. 600 MB, wo sind die 300MB???? ╮(╯▽╰)╭

-----------------------------------

Du hast recht!!! Meine restliche Code erzeugt viele Müll!!! Nach meinem Test mit Augenbeobachtung ist c.a 500 MB Müll während TXT lesen erzeugt. Ich weiß nicht, wie ich meine Code verbessern kann. Ich habe einfach BufferedReader benutzt, und ein paar short und float Varialbe, sonst nichts.

Aber trotzdem ist 1.4GB - 0.5GB = 0.9GB ein bisschen zu viel...

-------------------------------------

P.S: Ich mache mal meine Code sauber und post hier spät... :D Noch mal danke!
 

fatfox

Bekanntes Mitglied
Hi SlaterB,

Könntest du für mich mal prüfen, ob meine Code zu viele Platz verschwendet?

Hier ist meine Code:
Java:
import gnu.trove.TShortFloatHashMap;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import java.util.StringTokenizer;

public class Test {

	public static TShortFloatHashMap[] adjList ( String inputFile, int numberOfVertex ) {

		TShortFloatHashMap[] hm = new TShortFloatHashMap[numberOfVertex];

		for (int i = 0; i < numberOfVertex; i++) {
			hm[i] = new TShortFloatHashMap();
		}

		try {
			BufferedReader br = new BufferedReader(new FileReader(inputFile));
			String line = br.readLine();
			short s = 0, t = 0;
			Float leverage;
			StringTokenizer st;
 // Zeilen für Zeilen lesen:
			while (line != null) {
				st = new StringTokenizer(line, ";");
				leverage = Float.parseFloat(st.nextToken());
				s = Short.parseShort(st.nextToken());
				t = Short.parseShort(st.nextToken());
// Eintrag eingeben( In meine datei bietet eine Zeile die Informationen von 2 Einträge, deshalb zwei mal eingeben)
				hm[s].put(t, leverage);  
				hm[t].put(s, leverage);  
				
				line = br.readLine();
			}

			br.close();

		} catch (IOException e) {
			System.err.println(e.toString());
		}

		return hm;
	}


	public static void main(String[] args) {
		String inputFile = "/home/conny/Datei/Leverage_14842.csv";
		int numberOfVertex = 14842;
		
		adjList(inputFile, numberOfVertex);

	}

}

Und hier ist die Datei: http://www.phoenix-eyes.com/Diplom/Datei/Leverage_14842.csv
Datei ist groß, c.a. 268 MB °°°°°
 
Zuletzt bearbeitet:
S

SlaterB

Gast
bei mir werden ca. 700 MB belegt und das sind wie vermutet ca. 7 Byte pro Eintrag

allerdings sind es nicht 36 Mio. Einträge, sondern deutlich mehr, die Maps genehmigen sich noch viel mehr Platz als ich dachte,
am Ende 95 Mio. Einträge und mehr, das 2.6fache der eigentlich benötigten Menge,
soviel leerer Platz hilft wohl damit die Map effizient arbeitet, wenig Kollisionen der Hashwerte, was bei short sicher direkt die Keys sind,
vielleicht sorgen auch gerade die Kollisionen, die gleichen Keys, für mehr Platzbedarf,
müsste man im Detail nachschauen, aber das zumindest werde ich nicht mehr machen ;)

hier ein Programm mit Speichermessung, ordentlich System.gc() scheint bei mir zuverlässig temporären Speicher wieder frei zu geben,
ansonsten habe ich auch stark variierende Zahlen bis zu 1 GB

Java:
public class Test {
	public static TShortFloatHashMap[] adjList(String inputFile,
			int numberOfVertex) throws Exception {

		TShortFloatHashMap[] hm = new TShortFloatHashMap[numberOfVertex];
		for (int i = 0; i < numberOfVertex; i++) {
			hm[i] = new TShortFloatHashMap();
		}
		long start = mem("");
		BufferedReader br = new BufferedReader(new FileReader(inputFile));
		String line = br.readLine();
		short s = 0, t = 0;
		Float leverage;
		StringTokenizer st;
		int c = 0;
		// Zeilen für Zeilen lesen:
		while (line != null) {
			st = new StringTokenizer(line, ";");
			leverage = Float.parseFloat(st.nextToken());
			s = Short.parseShort(st.nextToken());
			t = Short.parseShort(st.nextToken());
			// Eintrag eingeben( In meine datei bietet eine Zeile die
			// Informationen von 2 Einträge, deshalb zwei mal eingeben)
			hm[s].put(t, leverage);
			hm[t].put(s, leverage);

			line = br.readLine();
			c++;
			if (c % 1000000 == 0) {
				long l = mem("");

				int sumcap = 0;
				for (TShortFloatHashMap map : hm) {
					sumcap += map.capacity();
				}
				System.out.println(c + ", " + sumcap + ", " + (l - start)
						+ ", " + ((l - start) * 100 / sumcap));
			}
		}
		br.close();
		return hm;
	}

	public static void main(String[] args) throws Exception {
		String inputFile = "/home/slater/Leverage_14842.csv";
		int numberOfVertex = 14842;
		System.out.println("start");

		mem("mem ");
		TShortFloatHashMap[] hm = adjList(inputFile, numberOfVertex);
		mem("meme");
	}

        // Achtung, jeder Aufruf dauert eine Sekunde
	private static long mem(String st) throws Exception {
		Runtime r = Runtime.getRuntime();
		System.gc();
		System.gc();
		System.gc();
		Thread.sleep(500);
		System.gc();
		System.gc();
		System.gc();
		long l = (r.totalMemory() - r.freeMemory());
		if (st.length() > 0) {
			System.out.println(st + ": " + l);
		}
		return l;
	}
}
Ausgabe:
Code:
start
mem : 110680
1000000, 5844348, 38536016, 659 // = 6.59 Bytes pro Capacity
2000000, 12115398, 82429904, 680
3000000, 17521210, 120267944, 686
4000000, 22577446, 155659656, 689
5000000, 28474044, 196934176, 691
6000000, 35032110, 242839104, 693
7000000, 41492600, 288061224, 694
8000000, 47375318, 329238760, 694
9000000, 53196416, 369985120, 695
10000000, 58794254, 409168576, 695
11000000, 64240364, 447289904, 696
12000000, 69400868, 483412424, 696
13000000, 74409500, 518471728, 696
14000000, 79607082, 554853728, 696
15000000, 84602812, 589822832, 697
16000000, 89622976, 624962928, 697
17000000, 95158938, 663713656, 697
meme: 691889264
 
Zuletzt bearbeitet von einem Moderator:

fatfox

Bekanntes Mitglied
Hi Slate,

Danke!!!!!!!!! :D Endlich habe ich das Problem verstanden!!!

Ich habe noch eine kleine Frage, warum hast du in "mem()" Funktion 6 mal [c]System.gc( )[/c] aufgerufen? Reicht einmal nicht?
 
S

SlaterB

Gast
kannst es ja ohne versuchen, nur einmal ohne sleep hat jedenfalls nicht bei mir gereicht,
ob mehrmals hilft kann ich nicht sicher sagen, ist vielleicht nur ein Gerücht, irgendwer hat es mal geschrieben, alle anderen machen es nach..
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D String Groß/Kleinschreibung Ignorieren Java Basics - Anfänger-Themen 4
S Datei anlegen Problem! Groß- und Kleinschreibung wird nicht unterschieden Java Basics - Anfänger-Themen 4
S Chars vergleichen ohne Betrachtung der Groß und Kleinschreibung Java Basics - Anfänger-Themen 7
T Feststellen, dass Wert zu groß; Caesar Chiffre Java Basics - Anfänger-Themen 3
N Groß- und Kleinschreibung bei Java: void Methode Java Basics - Anfänger-Themen 1
S Scanner soll Groß-/ Kleinschreibung ignorieren Java Basics - Anfänger-Themen 2
N Eingabe erkennen, ob groß oder kleingeschrieben worden ist Java Basics - Anfänger-Themen 22
B Regex ignorieren von Groß - Kleinschreibung Java Basics - Anfänger-Themen 1
Hanschyo Quicksort sortiert von groß nach klein Java Basics - Anfänger-Themen 3
CptK Interface Bilder über Bildschirm bewegen, bis der Abstand zum vorherigen zu groß wird Java Basics - Anfänger-Themen 13
B String: Groß- und Kleinschreibung ignorieren bei Contains? Java Basics - Anfänger-Themen 2
S Groß- und Kleinbuchstaben gleich behandeln Java Basics - Anfänger-Themen 3
MR._FIRE_Flower String Anfangsbuchstabe Groß Java Basics - Anfänger-Themen 23
K Sortierung eines int-Arrays von groß nach klein Java Basics - Anfänger-Themen 3
Bregedur String beim nächstem groß geschriebenen Buchstaben trennen Java Basics - Anfänger-Themen 1
D Groß/KleinBuchstaben zählen Java Basics - Anfänger-Themen 21
W Erste Schritte Erster Buchstabe groß bzw. klein???? Java Basics - Anfänger-Themen 2
S Groß bzw. Klein Buchstaben umwandeln (gemischt) Java Basics - Anfänger-Themen 1
M FileWriter Neue Datei wenn aktuelle "zu groß" Java Basics - Anfänger-Themen 3
S Fenster ist zu groß Java Basics - Anfänger-Themen 8
H Objekt zu groß zum Senden? Java Basics - Anfänger-Themen 6
M Methoden Groß- und Kleinschreibung Java Basics - Anfänger-Themen 3
I Input/Output Wortanfang groß schreiben Java Basics - Anfänger-Themen 5
D KeyListener, Unterscheidung Groß/Kleinbuchstaben Java Basics - Anfänger-Themen 3
S JTextArea mit LineWrap true viel zu groß! Java Basics - Anfänger-Themen 2
M Datentypen Wie groß kann ein Array max sein? Java Basics - Anfänger-Themen 9
N Variationen eines Strings - groß/klein Java Basics - Anfänger-Themen 3
T Border Layout alle mittleren felder gleich groß Java Basics - Anfänger-Themen 3
X Wie groß ist String[]? Java Basics - Anfänger-Themen 8
Daniel_L RegEx-Frage, Groß-/Kleinschreibung Java Basics - Anfänger-Themen 2
G Swing Komponente so groß wie Fenster Java Basics - Anfänger-Themen 10
P Swing Textarae so groß wie Panel? Java Basics - Anfänger-Themen 2
F Groß- und Kleinbuchstaben in String Java Basics - Anfänger-Themen 11
G Erster Buchstabe groß bzw. klein? Java Basics - Anfänger-Themen 4
T Ersten Buchstaben in einem Wort groß schreiben. Java Basics - Anfänger-Themen 6
M Palindrom mit Groß & kleinbuchstaben Java Basics - Anfänger-Themen 19
T Entwder char auf groß oder klein prüfen, oder Exception Java Basics - Anfänger-Themen 3
M Strings: Groß-Kleinschreibung ignorieren Java Basics - Anfänger-Themen 6
A Groß-/Kleinbuchstabe Java Basics - Anfänger-Themen 2
G Groß- und Kleinschreibung Java Basics - Anfänger-Themen 13
N Groß- und Kleinschreibung vertauschen? Java Basics - Anfänger-Themen 3
C ein Canvas ist zu groß. mit Scrollbar ? Java Basics - Anfänger-Themen 8
W Zahl für longtype zu groß? Java Basics - Anfänger-Themen 2
G Klasse zu groß (>3000 codezeilen). wie sinnvoll strukturi Java Basics - Anfänger-Themen 9
K Erster Buchstabe groß Java Basics - Anfänger-Themen 7
H Wie geht eigentlich Objektorientierung? Java Basics - Anfänger-Themen 14
P Methode die eigentlich einen Scanner benötigt mit toString() Java Basics - Anfänger-Themen 5
J Fehler beim generieren von 4 Zufallszahlen Zahl doppelt ist eigentlich ausgeschlossen Java Basics - Anfänger-Themen 9
V Bin eigentlich noch VOR dem Anfang .... Java Basics - Anfänger-Themen 9
M Warum ist Maven als Technologie eigentlich so sicher? Java Basics - Anfänger-Themen 0
X SAX Parser, wie weit ist der eigentlich? Java Basics - Anfänger-Themen 6
R Eigentlich richtig, eigentlich... Java Basics - Anfänger-Themen 4
C Erste Schritte was macht eigentlich "for (;;)" Java Basics - Anfänger-Themen 7
B String der eigentlich eine Ansammlung von HEX zeichen ist in datei schreiben in Hex Java Basics - Anfänger-Themen 8
S Erste Schritte Wo steht eigentlich das ein jar keine andere jars enthalten darf? Java Basics - Anfänger-Themen 19
D Muss ich eigentlich immer auf die Verwendung des richtigen Datentyps achten? Java Basics - Anfänger-Themen 7
D Ist es eigentlich ungünstig direkt in einem Konstruktor bereits umfangreichen Logikcode auszuführen? Java Basics - Anfänger-Themen 11
alderwaran closed source jar, kein javadoc. was macht methode x eigentlich? ( oracle forms pjc beans ) Java Basics - Anfänger-Themen 2
H Warum sind in Java Strings und Arrays eigentlich unveränderlich? Java Basics - Anfänger-Themen 2
T Interfaces: Braucht man abstrakte Klassen eigentlich noch? Java Basics - Anfänger-Themen 3
A [gelöst]Zwei Ausgaben, die eigentlich gleich sein sollten Java Basics - Anfänger-Themen 9
K Was bedeutet das eigentlich.... Java Basics - Anfänger-Themen 18
G Was ist eigentlich SWT? Java Basics - Anfänger-Themen 23
E Was ließt der BufferedReader eigentlich ein? Java Basics - Anfänger-Themen 3
S Desginfrage Interface - aber wozu eigentlich? Java Basics - Anfänger-Themen 2
N läuft der thread eigentlich weiter? Java Basics - Anfänger-Themen 13
G Warum eigentlich static void? Java Basics - Anfänger-Themen 3
N Welche software hab ich eigentlich ? Java Basics - Anfänger-Themen 17
S HashMap mehrere Keys zu einem Value Java Basics - Anfänger-Themen 3
A Daten aus einer HashMap aus einer DB speichern und mit neuen Werten vergleichen Java Basics - Anfänger-Themen 8
T HashMap Lsite gibt die sachen nicht aus wie gewollt. Java Basics - Anfänger-Themen 3
krgewb HashMap Java Basics - Anfänger-Themen 2
B Hashmap richtig bauen, die Tripel auf Zahl abbildet? Java Basics - Anfänger-Themen 10
"java.util.HashMap.get(Object)" is null Java Basics - Anfänger-Themen 10
berserkerdq2 Hashmap, wie prüfe ich ob ein Key schon existiert Java Basics - Anfänger-Themen 19
S Durch HashMap iterieren Java Basics - Anfänger-Themen 8
rafi072001 Sortieren einer HashMap nach Values Java Basics - Anfänger-Themen 2
F gson mit einer Hashmap Java Basics - Anfänger-Themen 2
J JSON-HashMap Java Basics - Anfänger-Themen 3
J Hashmap Java Basics - Anfänger-Themen 13
C Hashmap zickt Java Basics - Anfänger-Themen 9
S HashMap contains() Methode Java Basics - Anfänger-Themen 1
Z Satz aufteilen und die Wörter zählen (HashMap) Java Basics - Anfänger-Themen 15
N enum Attribut von Objekten einer Hashmap ausgeben Java Basics - Anfänger-Themen 6
P Verschachtelte Hashmap Java Basics - Anfänger-Themen 6
I Sortiert eine HashMap nicht gleich wie eine ArrayList? Java Basics - Anfänger-Themen 1
B HashMap alphabetisch sortieren Java Basics - Anfänger-Themen 2
J HashMap Java Basics - Anfänger-Themen 6
M Enum-Variable HashMap zuweisen Java Basics - Anfänger-Themen 5
U Hashmap Iterator selbst implementieren Java Basics - Anfänger-Themen 10
N HashMap in List good practice? Java Basics - Anfänger-Themen 2
K Value eines HashMaps in einer HashMap wiedergeben. Java Basics - Anfänger-Themen 5
O Hashmap, ArrayList, LinkedList Java Basics - Anfänger-Themen 7
O HashMap - ArrayList Java Basics - Anfänger-Themen 29
J Hashmap langsamer als compareTo? Java Basics - Anfänger-Themen 23
E HashMap+Vererbung Java Basics - Anfänger-Themen 11
J Erhöhen eines Values als Integer bei gleichen Keys in HashMap Java Basics - Anfänger-Themen 12
N Methoden HashMap interne Werte miteinander vergleichen Java Basics - Anfänger-Themen 7
W The type Long is not visible HashMap Java Basics - Anfänger-Themen 4
M Objekt mit Hashmap vergleichen Java Basics - Anfänger-Themen 22

Ähnliche Java Themen

Neue Themen


Oben