PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Brauche HIlfe von jemandem, der einen 2.6er Kernel laufen hat.



Anakin77
07.01.2004, 15:18
Kann bitte jemand mal das folgende Javaprogramm testen?

Die Links:

http://www.netphantom.de/down/Threadtest.class
http://www.netphantom.de/down/Threadtest.java

Das Programm benötigt eine Java Virtual Machine. Man kann es wie folgt starten:

java Threadtest.class 1024

Dies würde dann 1024 Threads erzeugen, welches unter einem 2.4er Kernel nicht funktioniert hat, da es dort eine Grenze gibt. Wenn also jemand einen laufenden 2.6er Kernel und eine JVM hat, dann würde ich mich sehr freuen, wenn er dieses kleine Programm mal testen könnte (wie viele Threads erzeugt werden können bevor eine Fehlermeldung wie OutofMemoryException erscheint).

Der Quellcode:



import java.lang.Thread;

public class Threadtest extends Thread
{
public static int threadcounter=0;
public Threadtest() {}

public static void main(String[] args)
{
Thread [] t = new Thread[20000];
Integer anzahl;
int anz=0;

// nur einen Parameter
if (args.length == 1)
{
// Übergebene Zeichenkette in int wandeln
try
{
anzahl = new Integer(args[0]);
anz = anzahl.intValue();
}
catch(Exception e)
{
System.out.println("Bitte gueltige Zahl zwischen
2 und 20000 eingeben!");
System.exit(2);
}

// 20000 Threads würden reichen !
if (anz>20000)
{
System.out.println("Maximum ist 20000!");
System.exit(2);
}

// Mehr Threads, sonst ist der Test sinnlos!
if (anz<2)
{
System.out.println("Minimum ist 2!");
System.exit(2);
}

System.out.print("Erzeuge ");
System.out.print(anz);
System.out.println(" Threads!");
Threadtest x = new Threadtest();

// gewünschte Anzahl Threads erzeugen. Referenzen in Thread-Array
for(int i=1;i<=anz;i++)
{
t[i] = new Thread(x);
t[i].start();
System.out.print("Thread Nummer ");
System.out.print(i);
System.out.println(" erzeugt!");
}

// Ende des Mainthreads!
System.out.print(threadcounter);
System.out.println(" Threads erfolgreich gestartet!");
}
else
{
System.out.println("Fehler: Anzahl der Threads (2-20000) als
Parameter, Bsp: java Threadtest 1000!");
}
}
public void run()
{
try {
// globalen Threadzähler erhöhen
threadcounter++;

// warten bis zum Crtl-C (oder der OutofMemoryException)
do
{ Thread.sleep(1000); }
while(true);
}
catch(Exception e){}
}
}

Zero
07.01.2004, 15:23
kriege nen fehler:

Exception in thread "main" java.lang.NoClassDefFoundError: Threadtest/class

Andre
07.01.2004, 15:23
ich schiebe das mal nach Java....

Anakin77
07.01.2004, 15:38
Sorry, das Kommando sollte wie folgt sein:

java Threadtest 1500

und nicht java Threadtest.class 1500

Dann sollte es starten!

Zero
07.01.2004, 15:40
1499 Threads erfolgreich gestartet :D

Anakin77
07.01.2004, 15:43
Vielen Dank für den Test.

Kannst du bitte noch das Ganze mal mit deutlich höheren Werten testen?

So mal 5000, 10000, 19000 (20000 akzeptiert das Testprog nicht mehr ^^).

Zero
07.01.2004, 15:49
hehe
das teil frisst ja meinen ram wie nix :D
Nachdem ich das progg 3 mal gestartet habe,
kommt folgende Meldung

bei 19000 und jeglicher anderer summe auch,
die nicht höher als eben die 20000 sind:

Thread Nummer 374
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start(Native Method)
at Threadtest.main(Threadtest.java:52)

Wenn ich jedoch als Startparamet die Zahl bis
373 eingebe, dann geht es einwandfrei.

Bei jeder Zahl über 374 kommt dann die
oben genannte Meldung.

HTH

EDIT:
Achja, habe 512 MB drinen, falls das von interesse ist,
wegen der Fehlermeldung ;)

Anakin77
07.01.2004, 15:55
Wie viele Threads liefen denn zu dem Zeitpunkt genau???

Mit welchen Parametern hast du es dreimal gestartet?

Zero
07.01.2004, 15:59
Beim ersten mal lief die 1500 komplett durch,
beim zweiten mal die 5000
und beim dritten mal die 19000

und beim vierten mal testete ich es mit 19500
da ist es eben bei 374 stehen geblieben.

Das fünfte mal teste ich es mit 373.

meez
14.01.2004, 21:40
Warum soviele Threads ?
Mehr als 50 sind ehh sinnlos, da der Prozess sonst mehr mit der Verwaltung der Thread zu tun hat, als mit den "wirklichen" Operationen...

Wenn dus aber dennoch versuchen willst, mach folgendes:

Aendere deinen Code. Einen Thread Feld mit 20000 Plätzen :Kopfschüttel:
Lösch den Array und erzeuge die Threads so (spart Speicherplatz):

for (int i=1;i<anz;i++) {
new Threadtest().start();
System.out.println(...);
}

(Falls du die Refernz auf den Thread noch brauchen solltest, lege sie in einen Vector)

Zudem starte die JVM (Hotspot-Engine) so:
java -Xms2m -Xmx2m -Xss2m Threadtest

hehejo
15.01.2004, 08:50
Zudem starte die JVM (Hotspot-Engine) so:
java -Xms2m -Xmx2m -Xss2m Threadtest

Was bringt das? HotSpot-Engine hab ich schon mal gehört.. aber was ist das gleich noch mal?

hehejo
15.01.2004, 09:04
Achtung: Alles nur Vorschläge, keine Kritik!



catch(Exception e)
{
System.out.println("Bitte gueltige Zahl zwischen 2 und 20000 eingeben!");
System.exit(2);
}

Es ist besser immer nur die Exceptions abzufangen die man auch haben will.
Mit "catch(Execption e)" fängst du alles ab! Ein "catch(NumberFormatException e)" ist da besser.


System.out.print("Erzeuge ");
System.out.print(anz);
System.out.println(" Threads!");

Ist jetzt zwar kniefieselig, aber warum nicht in einer Zeile?
"System.out.println("Erzeuge" + anz + " Threads!");"
Hat den Vorteil, dass du die Funktion nur einmal aufrufst. Außerdem wird die Mehthode um sage und schreibe zwei Zeilen kürzer.. :)

Falls du nicht weißt was ein Vector ist: (wusste ich bis vor kurzem auch nicht, obwohl ich es dringend gebraucht hätte!)
Ein Vector ist eine Klasse die eine beliebige Anzahl von Objects aufnimmt. Du kannst also immer mehr reinstecken ohne dich um Speicher kümmern zu müssen.

Viel Spaß mit Java, wünscht

meez
15.01.2004, 09:15
Was bringt das? HotSpot-Engine hab ich schon mal gehört.. aber was ist das gleich noch mal?

Setzt das Memory und den Thread Stack size der VM auf das Maximum (2 Giga)...Hab gleich noch einen Fehler gesehen: Es sollte heissen:
java -Xms2g -Xmx2g -Xss2g Threadtest


Die Hotspot-Engine ist ein Teil der JVM. Sie kümmert sich z.T. um die Speicherverwaltung.



Ein Vector ist eine Klasse die eine beliebige Anzahl von Objects aufnimmt....

Ein Vector nimmt nur die Referenz (Pointer) auf ein Objekt auf...Kommt aber aufs gleiche raus...



Ach ja...Die Klasse Thread muss nicht importiert werden, da java.lang.* und java.object.* sowieso immer import werden....

Anakin77
15.01.2004, 10:06
Leute, Leute

Meine Frage bezog sich nicht auf Programmiertechniken. Ich hatte diesen Thread auch ursprünglich nicht im Java-Forum. Irgendein Admin hat ihn scheinbar zu wenig gelesen und deshalb nach Java verschoben!

Klar könnte ich nen Vector nehmen. Ich könnte auch hunderttausend Exceptions abfangen und ne schöne bunte Oberfläche basteln.

Aber ich will doch nur testen, wie viele Threads erzeugt werden können.

Warum also soll ich die Exception abfangen? Ob die JVM oder ich die Meldung ausgibt ist mir ziemlich egal!

Ich habe nur das Problem, dass ich keinen 2.6er Kernel bei mir zum Fliegen bekommen habe, deshalb suche ich Leute die das Programm starten und nicht verbessern!

Anakin77
15.01.2004, 10:14
Setzt das Memory und den Thread Stack size der VM auf das Maximum (2 Giga)...Hab gleich noch einen Fehler gesehen: Es sollte heissen:
java -Xms2g -Xmx2g -Xss2g Threadtest
...

Nun, ich bin mir nicht sicher, wie es die JVM unter Linux machen. Aber die SUN-JVM unter Windows oder auch die von IBM für AIX hätten damit ein große Probleme.

Wenn du die initial Heapsize (Xms2g) auf 2GB setzt, dann kannst du fast keine Threads mehr erzeugen!

Erfahrungsgemäß kann ich mehr Threads laufen haben, wenn die Heapsize auf 1GB oder niedriger ist. Ich kenne das interne Speichermanagement nicht, aber ich vermute mal ganz stark, dass der Stack pro Thread bzw. Heap pro Thread nicht von diesem beim Start reservierten Speicher genommen wird.

Anakin77
15.01.2004, 10:25
Warum soviele Threads ?
Mehr als 50 sind ehh sinnlos, da der Prozess sonst mehr mit der Verwaltung der Thread zu tun hat, als mit den "wirklichen" Operationen...


Mir geht es nicht darum ein Programm zu entwickeln, welches so viele Threads verwendet. Auch MySQL verwendet bei vielen (gleichzeitigen) Anfragen schon mal mehr als 1000 Threads. Und du kannst wohl nicht behaupten, dass MySQL zu langsam ist oder einfach nur schlecht programmiert wurde.

Mir geht es darum unseren Applicationserver (der nunmal auf anderen Plattformen in der Lage ist 5000 Clients und damit 15.000 Threads zu verwalten!!!) auch für Linux zum Laufen zu bekommen.

Es war bisher nämlich ziemlich peinlich, wenn ich immer sagen musste:

"Nehmt Windows, das hat ein besseres Threadmanagement als Linux".

Es ist aber auch Fakt, dass neben Windows andere UNIX-Derrivate damit viel besser umgehen als Linux.

Unter SUN Solaris und IBMs AIX kann ich problemlos mehr als 10.000 Threads erzeugen. Warum ist das so? Nun ja, Hauptproblem beim 2.4er Kernel war, dass Linux pro Thread mal eine Stacksize von 2MB anlegt. Diese ist in der Praxis absolut nicht nötig, sorgt aber dafür, dass mein kleines Testprogramm eben bei 1007 Threads (und unser Application Server bei 334 Userconnections) eine OutOfMemoryException wirft. Wers noch nicht gemerkt hat: Unser Applicationserver legt drei Threads pro Clientverbindung an :D

Ich habe halt die Hoffnung, dass Linux mit 2.6er Kernel nun endlich auch eine Alternative für unsere Kunden sein wird. Bisher mussten wir allen leider abraten Linux zu verwenden!

hehejo
15.01.2004, 11:22
wow..
Dass es um so was Großes geht hätte ich jetzt nicht gedacht.
Kann man beim Kernelbau die StackSize angeben?
Aber das wär dann ja auch nichts für Kunden..

Anakin77
15.01.2004, 12:23
Man kann.

Genauer gesagt muss man in limits.h und noch einer Headerdatei der GLIBC die Parameter anpassen.

Dort gibt es ein statisches Threadmaximum und eine Stacksize.

Leider ist es mir nie gelungen ein Linux zu booten, nachdem ich die GLIBC neu kompiliert hatte. Da ich aber in der CT gelesen habe, dass die Threadverwaltung unter Kernel 2.6 extrem verbessert worden sein soll, muss ich das nun testen.

Wir haben einige Kunden, die gerne Linux genommen hätten und nun entweder bei Windoof oder (falls genug Geld vorhanden ist) bei IBM AIX gelandet sind.

Ein Bekannter von mir hat meine Threadtest-Klasse auf einem Mandrake mit 2.6er Kernel leider nur mit 2000 threads zum Laufen bekommen. Er hat aber nicht mit verschiedenen JVMs inkl. anderer Parameter getestet. Das ist zwar immerhin das Doppelte im Vergleich zum 2.4er Kernel, aber bei Weitem nicht ausreichend für unsere Zwecke. Bislang können wir uns nur helfen, indem wir mehrere Applicationserver (in mehreren JVMs) starten. Dadurch bekommen in der Summe ausreichend Userconnections hin. Da dies aber inkl. Loadbalancing komplexer zu konfigurieren ist (auch virtuelle IPs werden dann benötigt) ist es leider nicht das "gelbe vom Ei".

Ich hoffe, dass bald eine Distri mit 2.6.1 raus kommt, denn ein Patchen des Kernels oder der GLIBC ist auf Kundenseite nur bei einem Teil unseer Kunden möglich. Prinzipiell könnten wir unsere Software komplett vorinstalliert auf einem Linuxrechner liefern, insofern würde das auch helfen. Wenn aber in Kürze sowieso eine Distri rauskommt, die dieses Problem nicht mehr hat, wäre dies natürlich für alle Seiten am Besten.

meez
15.01.2004, 13:40
Wenn du die initial Heapsize (Xms2g) auf 2GB setzt, dann kannst du fast keine Threads mehr erzeugen!



Das ist nicht der "eigentliche " Heap-Size, sondern der allozierte Speicher... Der Heap-Size bezieht sich auf duie neu ertsellten Objekte.

Starte die VM so:

java -server -Xms2g -Xmx2g -XX:NewSize=512 -XX:MaxNewSize=512 Threadtest

Anakin77
15.01.2004, 13:48
hmm, wie gesagt, ich habe die anderen Parameter unverändert belassen aber den allozierte Speicher vergrößert. Dies hatte zur Folge, dass ich weniger Threads erzeugen konnte.

Deshalb verwende ich bisher -xms500k -xmx500k

Damit geht einiges mehr als wenn ich 2GB verwende.

Es klingt zwar widersinnig, aber wenn ich die JVM mit mehr Speicher starte, dann bekomme ich früher die OutofMemoryException

sule74
14.02.2006, 11:18
Hallo Anakin77,

die Anzahl der Java-Threads die erzeugt werden koennen,
haengt wesentlich davon ab, wie die stackgroesse mit ulimit -s gesetzt ist.
Halbiert man diesen Wert, verdoppelt sich in etwa die Anzahl der erzeugbaren Threads..
Nebenbei: Ich verwende noch Java1.3 mit kernel 2.6.9-22.0.2.ELsmp



# ulimit -s 20480
#java -Xmx32m -Xms32m -Xss512K -XX:MaxPermSize=4m Threadtest 1000
..
Thread Nummer 138 erzeugt!
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start(Native Method)
at Threadtest.main(Threadtest.java:52)


# ulimit -s 10240
#java -Xmx32m -Xms32m -Xss512K -XX:MaxPermSize=4m Threadtest 1000
..
Thread Nummer 287 erzeugt!
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start(Native Method)
at Threadtest.main(Threadtest.java:52)

Xanti
14.02.2006, 11:21
Asbach Uralt...

gulpi
29.06.2006, 09:59
Erfahrungsbericht zum Thema:

Ich hatte Probleme bei eine Umstellung auf Tomcat 5.5 mit Java 1.5. Nach gewisser Laufzeit im Produktionsbetrieb blieb der Container hängen, Auszug aus catalina.out:

28.06.2006 22:27:31 org.apache.tomcat.util.threads.ThreadPool$ControlR unnable run
SEVERE: Caught exception (java.lang.OutOfMemoryError: unable to create new native thread) executing org.apache.jk.common.ChannelSocket$SocketAcceptor@ d4694f, terminating thread

Das ganze auf einem PIV Server, 2G, Suse 9.3 mit neusten Patches, tomcat und Java allerdings selbst installiert kein Pakete von Suse verwendet.

Mit dem hier gepostet Code habe ich dann rumgespielt. Bei Java1.5 war bei 53 Threads Ebbe, bei der älteren Java 1.4 Version 1000 Threads kein Problem. Spielen mit den -X Optionen: Kein Effekt, nachvollziehbar stieg das Testprogramm genau wie Tomcat nach genau 53 Threads aus....... unabhängig von den Startoptionen!?!?!?!

Lösung auch hier wie oben angedeutet: ulimit -s

Egal was für ein Zahlenwert gesetzt wurde: 53 Threads!!!
ulimit -s unlimited: Yeah!! jetzt ist bei ca. 800 Threads Ebbe, was aber VIEL MEHR als ausreichend für meine Zwecke ist!!!

Kleine Parameter, grosse Wirkung.....

Danke für alle Postings, haben mir zumindest ein bisschen Zeit gespart, da sie mich schneller auf die richtige Fährte gebracht haben!

Cheers
Gulpi