nicht genug speicher - profiling trotz error

Status
Nicht offen für weitere Antworten.

dermoritz

Bekanntes Mitglied
ich hab ein speicherproblem mit meinem programm (out of memory), hab die vm schon auf "-Xms512m -Xmx1200m" also max 1,2gb. ich benutze eclipse mit dem profiling paket (Eclipse Test & Performance Tools Platform). aber entweder lese ich es falsch oder es ist nicht aussagekräftig solange das programm läuft.

jedenfalls zeigt es mir maximal einige mbyte unter total size an - die summer aller "total size" sollte unter 20mb liegen.

kann mir jemand mal bitte sagen ob und wie man in so einem fall vorgeht? (andere tools? andere einstellung des profilers?)


zum programm: das es viel speicher verbraucht ist normal (ich berechne das kartesische produkt von mengen) die frage ist wo da noch luft ist - eventuell hab ich auch irgendwo fehler bzw. kann zumindest halbieren oder so. ein profiler würde mir halt helfen wo zu suchen ist.
 
Speicherengpässe kann es ja nicht nur beim Heap, sondern auch beim Stack geben - dann hilft -Xmx natürlich nichts. Das sieht man aber am Stack-Trace.
 
da beim erhöhen der oben genannten zahlen das programm viel länger läuft würd ich sagen ich hab den engpass gefunden. ich hab inzwischen das problem so klein gemacht das ich es per tptp profilen kann, aber das nützt mir gar nix.

bei einer memory analyse kommt raus das der meiste speicher für byte[] draufgeht. ich kann nicht sehen bei welcher methode oder welcher oberklasse das byte[] so groß wird.


feherlausgabe:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)
at ect.stimuli.Stimuli.cartProduct(Stimuli.java:89)
at ect.stimuli.UntimedStimuli.<init>(UntimedStimuli.java:50)
at ect.main.Ect.main(Ect.java:91)

die funktion die den speicher frisst ist genau die die ich verdacht hab:

Code:
	public static <T> List<List<T>> cartProduct(final List<List<T>> sets, final int dt_factor) {
		List<List<T>> cartesian_product = new ArrayList<List<T>>();
		List<T> cartesian_product_element;
		int n = 1;
		Iterator<List<T>> sets_it = sets.iterator();
		// loop to get cardinality of Cartesian product
		while (sets_it.hasNext()) {
			List<T> set = sets_it.next();
			n *= set.size();
		}
		for (int i = 0, times = 1; i < sets.size(); times *= sets.get(i).size(), i++) {
			cartesian_product_element = new ArrayList<T>();
			List<T> set = sets.get(i);
			for (int j = 0; j < n / (times * set.size()); j++) {
				for (T element : set) {
					for (int k = 0; k < (times * dt_factor); k++) {
						cartesian_product_element.add(element);
					}
				}
			}
			cartesian_product.add(cartesian_product_element);
		}
		return cartesian_product;
	}

sie bildet ein kartesisches produk folgender form:
z.b. für die mengen (a,b,c) und (1,2,3):
aaabbbccc
123123123

nun stelle man sich das ganze mit 10 mengen vor mit im schintt 5 elementen -> 5^10. die frage wäre nun kann ich die oben genannte funtion irgendwie optimieren oder bin ich schon beim minimalen speicherverbrauch?
 
müssen es listen sein? da du die größe des kartesichen produkts ja schon im vorhinein kennst, könntest du auch ein array nehmen, dessen elemente sets sind. und wieso nimmst du überhaupt listen um sets zu implementieren....wenn es doch sets gibt? arraylist ist ohnehin nicht gerade die beste lösung für große datenmengen, erst recht wenn man dem konstruktor keine angemessene anfangsgröße übergibt.
 
die äußere struktur könnte durchaus ein array sein aber die innere struktur - also die art der menge muss beliebig sein. kann man ein array auf einem generischem typ bilden? ich glaub das geht nich so richtig?!

aber letztendlich löst es das eigentliche problem nicht: die speicherkomplexität.

ab einer bestimmten problemgröße würde der error immer kommen. die frage ist ob man das ganze etwas speciher schonender implementieren kann?!
 
also die speicherkomplexität sollte "noch" kein problem sein. bzw. sollte ich mit 1gb heap size lange reichen?!

in dem speziellen fall hat das cartesische produkt z.b. ca 11mio elemente. die struktur speichert aber nur referenzen auf die jeweiligen elemente. d.h. ich hab nur so viel objekte wie ich ursprünglich elemente hab, aber eine riesige menge referenzen.

mein hauptproblem is eben das ich keine ahnung hab wie ich vernünftig in eclipse den speicher überwachen kann. denn das was mir tptp anzeigt ist ja bei weitem entfernt von irgendwelchen grenzen.

ich würde als erstes gerne mal sehen wie groß die heap size für ein gegebenes problem ist - ich weiß eben nur das für 11mio elemente 1,2gb nicht reichen und für ein fünftel davon auch nicht.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben