Brauche HIlfe von jemandem, der einen 2.6er Kernel laufen hat.

A

Anakin77

Mitglied
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:

Code:
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){}
    }
}
 
Zuletzt bearbeitet:
kriege nen fehler:

Exception in thread "main" java.lang.NoClassDefFoundError: Threadtest/class
 
Sorry, das Kommando sollte wie folgt sein:

java Threadtest 1500

und nicht java Threadtest.class 1500

Dann sollte es starten!
 
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 ^^).
 
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 ;)
 
Zuletzt bearbeitet:
Wie viele Threads liefen denn zu dem Zeitpunkt genau???

Mit welchen Parametern hast du es dreimal gestartet?
 
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.
 
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
 
meez schrieb:
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?
 
Achtung: Alles nur Vorschläge, keine Kritik!

Anakin77 schrieb:
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.

Anakin77 schrieb:
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
 
hehejo schrieb:
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.


hehejo schrieb:
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....
 
Zuletzt bearbeitet:
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!
 
Zuletzt bearbeitet:
meez schrieb:
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.
 
meez schrieb:
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!
 
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..
 
Kernelkonstanten?

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.
 
Zuletzt bearbeitet:
Anakin77 schrieb:
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
 
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
 

Ähnliche Themen

Input == String => false

Java 1.3 ORO Regex Problem

Performant Scrollen

NagiosGrapher 1.7.1 funktioniert nicht

Problem bei Berechnung

Zurück
Oben