Linux vs. Windows (Split aus: Allgemeine Funktion um verfügbaren Speicher zu ermitteln?)



  • SeppJ schrieb:

    Ich könnte also ein Windowssystem mit

    while(True) calloc(1, 1);
    

    mit einem Schlag lahmlegen?

    Nette Idee 🙂 Ich habs letzten Freitag bei der Arbeit mal ausprobiert und Win10 damit zum Stillstand gebracht.

    Es wäre interessant, das Experiment mit einem Rechner ohne Pagefile zu wiederholen, ich vermute nämlich, daß der Stillstand daher rührt, daß Windows zum Schluß nur noch mit Paging beschäftigt ist (was bei diesem Rechner besonders schwerwiegend ist, da er noch eine HDD verwendet).

    SeppJ schrieb:

    Wie viele Programme haben unabsichtliche Speicherlecks und wie viele haben unabsichtliche Threadlecks?

    Ob dein Programm ein Speicherleck hat, oder ob es unerbittlich und von fehlschlagenden Allokationen unbeeindruckt jeden freiwerdenden Speicherblock absorbiert, ist ja wohl ein Unterschied. Und Windows ist durchaus in der Lage, gewöhnliche Speicherknappheit zu erkennen, und zeigt dann eine Warnmeldung an, die auch anbietet, den Speicherfresser zu terminieren: https://i.stack.imgur.com/HkjXK.png.

    Durch dieses Verhalten erklärt sich auch meine Erfahrung, daß man (Desktop-)Windows besser mit Pagefile betreiben sollte, besonders wenn man nur 3 oder 4 GB RAM im Rechner hat (was an sich für sehr viele Anwendungsfälle vollkommen ausreicht). Solange ein Pagefile da ist, ist Overcommitting kein Problem, aber andernfalls sieht man öfters solche Dialoge oder gar Fehlverhalten von Programmen, die mit out-of-memory nicht zurechtkommen.



  • Forkstackerdriver schrieb:

    hustbaer schrieb:

    Forkstackerdriver schrieb:

    Ich setze bei den OOM-Kills schon voraus, dass man geziehlt bestimmte Prozesse davon ausschliessen kann.
    Habe mal den ersten google-Treffer herausgesucht: http://elixir.free-electrons.com/linux/v4.1/source/mm/oom_kill.c#L140
    Da gibt es auf jeden fall bool unkillable_task() .

    Wo, "da"? [...] Kandidat für was?

    na da, gleich am Anfang in der verlinkten Funktion wird auf unkillable_task getestet. Aber ich bin kein Kernelprogrammierer. Bin wie gesagt davon ausgegangen, dass man da Einfluss nehmen kann.

    Meinst du oom_unkillable_task ? Die Implementierung davon steht direkt über der von dir verlinkten. Ich sehe da nix was für mich so aussieht als ob man da seinen Prozess irgendwie "registrieren" könnte.

    Forkstackerdriver schrieb:

    Kandidat um in die Liste an Prozessen aufgenommen zu werden, die nicht "einfach" so gekillt werden.
    Wenn entsprechende wichtige Prozesse am Leben bleiben, können auch die Fehlerhaften Prozess einfach neu gestartet werden. Dazu braucht es keinen Systemreset.

    Naja...
    Wenn das Programm selbst sagen kann "ich darf nicht OOK-gekillt werden", dann ist der OOM-Killer auch wieder für die Würste. Dann hast du den Bug nämlich in einem Programm welches, weil der Programmierer ja sooooooo schlau war, sich als "darf nicht OOK-gekillt werden" flaggt, aber trotzdem ein böses Leak enthält.
    Und wenn es eine vom Sysop definierte Liste gibt, dann hast du quasi das selbe Problem, nämlich dass der Sysop sich für schlau hält und ein Programm einträgt dass dann doch wieder leakt.

    Der OOM Killer bringt also vielleicht für Desktops 'was, wenn man davon ausgeht dass der Benutzer schlau genug ist nicht stundenlang Fehler zu suchen nur weil der OOM-Killer ihm was weggeschossen hat. Weil der PC dann bedienbar bleibt und er nicht alle ungespeicherten Daten verliert. Für Server aber IMO eher nicht, weil es IMO recht viel Aufwand ist das System so zu konfigurieren, dass alles immer zuverlässig neu gestartet wird wenn es OOM-weggeschossen wird.
    Speziell auf Windows wo man nicht einfach "starte das Service neu" in den Service-Optionen reinklickt wenn man möchte dass ein Service im Fehlerfall neu gestartet wird. Wenn man Glück hat bringt das service nen eigenen Watchdog mit. Und wenn nicht, dann darf man selbst Bashen oder sonstwas. Und dann natürlich alle Varianten testen, also alle möglichen Reihenfolgen in denen einer (oder mehrere) der 20 Prozesse die man in "modernen" Anwendungsstacks so braucht weggeschossen und dann neu gestartet werden. Hui.

    Die robustere Variante ist da IMO echt einfach die ganze Kiste durchzustarten.



  • hustbaer schrieb:

    Meinst du oom_unkillable_task ? Die Implementierung davon steht direkt über der von dir verlinkten. Ich sehe da nix was für mich so aussieht als ob man da seinen Prozess irgendwie "registrieren" könnte.

    ja, fiel mir später auch auf. Aber zur Not könnte man das ja selbst erweitern bzw. wenn das wirklich ein gängiges Problem darstellen sollte, haben das sicherlich schon andere gemacht.

    Wenn das Programm selbst sagen kann "ich darf nicht OOK-gekillt werden", dann ist der OOM-Killer auch wieder für die Würste. [...]
    Und wenn es eine vom Sysop definierte Liste gibt, dann hast du quasi das selbe Problem, nämlich dass der Sysop sich für schlau hält und ein Programm einträgt dass dann doch wieder leakt.

    Ich meinte natürlich, dass der Admin das macht. Denke nicht, dass man dessen Unfähigkeitsfaktor mit in die Gleichung aufnehmen muss.

    Der OOM Killer bringt also vielleicht für Desktops 'was, wenn man davon ausgeht dass der Benutzer schlau genug ist nicht stundenlang Fehler zu suchen nur weil der OOM-Killer ihm was weggeschossen hat.

    Ob ein Prozess gekillt wird weil er zu viel Speicher benoetigt oder einfach wegen einer Zugriffsverletzung, kommt ja aufs selbe hinaus. In beiden Fällen steht eine ensprechende Meldung im syslog. Den PC neustarten, weil ein Userspace-Prozess den falschen Speicher schreibt? Die Win9x-Zeiten sind ja zum Glück vorbei.

    Für Server aber IMO eher nicht, weil es IMO recht viel Aufwand ist das System so zu konfigurieren, dass alles immer zuverlässig neu gestartet wird wenn es OOM-weggeschossen wird.

    Ich glaube du siehst das etwas zu schwarz. Es ist ja nicht so, dass wahllos irgendwelche Prozesse abgeschossen werden sondern normalerweise trifft es schon den richtigen.


  • Mod

    Kleiner Einwurf ohne alles gelesen zu haben: für den Task Manager wird unter Windows bereits beim Booten genügend Speicher reserviert. Auch die notwendigen GDI-Handles werden afaik reserviert. Somit sind immer genügend Speicher/Handles verfügbar um den Task Manager zu starten und Prozesse abzuschießen.

    MfG SideWinder



  • Hat jemand eine Erklärung dafür, dass unter Kubuntu LaTeX schneller läuft als auf Windows?



  • cvxvvcx schrieb:

    Hat jemand eine Erklärung dafür, dass unter Kubuntu LaTeX schneller läuft als auf Windows?

    Ich würde davon ausgehen, dass das an der enormen Menge an Konsolenausgaben liegt, die Latex standardmäßig macht. Die Windows-Konsole bremst enorm. Gib mal -quiet mit an, und schau, ob es besser wird.



  • Mr X schrieb:

    cvxvvcx schrieb:

    Hat jemand eine Erklärung dafür, dass unter Kubuntu LaTeX schneller läuft als auf Windows?

    Ich würde davon ausgehen, dass das an der enormen Menge an Konsolenausgaben liegt, die Latex standardmäßig macht. Die Windows-Konsole bremst enorm. Gib mal -quiet mit an, und schau, ob es besser wird.

    Ich führe LaTeX aus TeXstudio aus, also keine Konsole. Meine Vermutung ist, dass Linux Festplattenzugriffe cached.



  • Viele Linux-Programme laufen unter Windows langsamer, ist auch mit Git so. Warum sollte Latex da anders sein?
    Gibt verschiedene Gründe, z.B. weil ein Posix-Wrapper genutzt wird (Cygwin), oder weil nicht die nativen APIs benutzt werden... außerdem funkt andauernd der Virus-Scanner dazwischen, der ja seit Windows 7 standard ist.



  • Auch sind diverse File-System Sachen auf Windows leider immer noch langsamer als auf Linux. Bzw. umgekehrt: auf Linux sehr schnell. Daher enthalten viele Programme die in der Linux Welt entstanden sind viele File-System Calls. Was oft durch ne andere Architektur vermeidbar wäre, nur wenn kein guter Grund dagegen spricht, weil die Performance auf Linux eh gut genug ist, dann kann man es ja ruhig so machen. Beim Portieren auf Windows ist es dann langsam, nur bei nem Port kann man an der Architektur natürlich nix mehr ändern. Sonst wäre es ja kein Port sondern quasi ne Neuentwicklung.

    Ich hoffe allerdings immer noch dass sich da früher oder später mal 'was tun wird. Entweder dass ReFS weiterentwickelt wird, vielleicht so weit dass man es als Boot-FS verwenden kann, und da dann auch die Performance passt, oder dass MS es mit NTFS irgendwie hinbiegt.



  • SideWinder schrieb:

    Kleiner Einwurf ohne alles gelesen zu haben: für den Task Manager wird unter Windows bereits beim Booten genügend Speicher reserviert. Auch die notwendigen GDI-Handles werden afaik reserviert. Somit sind immer genügend Speicher/Handles verfügbar um den Task Manager zu starten und Prozesse abzuschießen.

    Hast du dazu einen Beleg, oder erinnerst du dich, woher du die Information hast? Würde mich interessieren.



  • Mich auch. Ich glaub das nömlich nicht so ganz. Weil halt das Ergebnis meines Versuchs dagegen spricht. Und weil es mMn. sehr viel Aufwand wäre. Da müsste man den Task-Manager schon in den Desktop-Window-Manager einbauen -- und das ist er AFAIK nicht.


  • Mod

    Ich wage mich zu erinnern, dass ich das auf Raymond Chans Blog (the old new thing) gelesen habe, kann es aber gerade nicht mehr finden. Da eure empirischen Ergebnisse anders sind, nehme ich die Aussage mal wieder zurück.

    Evtl. wars auch nur der Secure Desktop den man mit CTRL+ALT+DEL immer starten kann...

    MfG SideWinder



  • Hab's grad nochmal ausprobiert mit Testlimit.exe -m
    Weder der CTRL+ALT+DEL Screen noch der Taskmanager können mehr gestartet werden (Windows 10 x64 1703).

    Kann gut sein dass das mit dem CTRL+ALT+DEL Screen in älteren Windows Versionen mal garantiert war, aber aktuell ist es das ganz offensichtlich nicht (mehr).
    Gibt sogar ne schöne Fehlermeldung wo steht dass der Screen leider nicht angezeigt werden kann - vielleicht ist jetzt nur mehr Speicher für diese Fehlermeldung reserviert 🤡

    Ist natürlich schon doof irgendwie. Aber einfach Prozesse wegschiessen finde ich wie gesagt auch nicht gut. Die Variante mit "garantiert dass Task-Manager immer angezeigt werden kann" wäre da schon besser. Bringt aber auch nur was wenn man vor der Box sitzt. Denn per Remote-Desktop braucht man garantiert nicht versuchen sich in so einer Situation noch einzuloggen 🙂



  • SideWinder schrieb:

    für den Task Manager wird unter Windows bereits beim Booten genügend Speicher reserviert. Auch die notwendigen GDI-Handles werden afaik reserviert. Somit sind immer genügend Speicher/Handles verfügbar um den Task Manager zu starten und Prozesse abzuschießen.

    Was ich mich während dieser Diskussion auch schon gefragt habe: Wieso kommt das Betriebssystem überhaupt in die Situation, dass Prozesse abgeschossen werden oder gar das ganze System neugestartet werden muss? Wir haben genug Speicher, von dem sich das OS etwas abschneiden kann.



  • das eigentlich Traurige daran finde ich, dass wir als Programmierer uns so viel Mühe geben um NULL-mallocs und bad_allocs abzufangen und am Ende dann nur SIGTERM kommt 😞



  • Forkstackerdriver schrieb:

    Was ich mich während dieser Diskussion auch schon gefragt habe: Wieso kommt das Betriebssystem überhaupt in die Situation, dass Prozesse abgeschossen werden oder gar das ganze System neugestartet werden muss? Wir haben genug Speicher, von dem sich das OS etwas abschneiden kann.

    Das Betriebssystem hat da kein Problem, das läuft eh weiter. Bloss wenn du keine neuen Prozesse mehr starten kannst, weil kein Speicher mehr da ist... dann tut man sich auch schwer bestehende Prozesse zu beenden, damit wieder Speicher frei würde... weil man üblicherweise nicht gerade ein Tool offen hat mit dem man so nen Prozess abschiessen kann.



  • hustbaer schrieb:

    Forkstackerdriver schrieb:

    Was ich mich während dieser Diskussion auch schon gefragt habe: Wieso kommt das Betriebssystem überhaupt in die Situation, dass Prozesse abgeschossen werden oder gar das ganze System neugestartet werden muss? Wir haben genug Speicher, von dem sich das OS etwas abschneiden kann.

    Das Betriebssystem hat da kein Problem, das läuft eh weiter. Bloss wenn du keine neuen Prozesse mehr starten kannst, weil kein Speicher mehr da ist... dann tut man sich auch schwer bestehende Prozesse zu beenden, damit wieder Speicher frei würde... weil man üblicherweise nicht gerade ein Tool offen hat mit dem man so nen Prozess abschiessen kann.

    nach der Logik könnte das OS ja einfach ein Tool offen halten mit dem man den Prozess abschiessen kann 🕶



  • Will aber vor allem nochmal auf meinen anderen Einwand aufmerksam machen: Wieso prüfe ich eigentlich noch den Rückgabewert von malloc()?

    Das ist sehr demotivierend.



  • Ich bin nicht sicher, aber ich würde vermuten dass speziell grosse Allocations auch auf Systemen mit OOM-Killer schief gehen können. Möglicherweise (vermutlich) auch kleine, wenn zu viele kleine Allokationen in zu kurzer Zeit passieren.
    Ich vermute dass es beim OOM-Killer eher darum geht dass das System "verwendbar" bleibt bzw. es nach recht kurzer Zeit wieder wird -- und nicht dass jede einzelne Allokation garantiert wird.

    Und wenn diese Vermutungen zutreffen, dann heisst das dass du trotzdem den Returnwert von malloc prüfen solltest wenn du willst dass dein Programm in solchen speziellen Situationen nicht trotzdem abkackt.

    Wenn du willst kannst du aber natürlich ne eigene malloc Implementierung schreiben die nen Haufen retries macht mit ein bisschen sleep() dazwischen. Und dann nach einer bestimmten Zeit, wenns bis dahin immer noch nicht geklappt hat, einfach abort() aufruft. Dann musst du den Returnwert nicht mehr prüfen 😉

    Und natürlich willst du in 32 Bit Prozessen immer den Returnwert von malloc() prüfen.



  • hustbaer schrieb:

    Und wenn diese Vermutungen zutreffen, dann heisst das dass du trotzdem den Returnwert von malloc prüfen solltest wenn du willst dass dein Programm in solchen speziellen Situationen nicht trotzdem abkackt.

    Den Rückgabewert von malloc muss man natürlich immer prüfen.
    Ich will doch hoffen, das selbst bei 64 bit, malloc(-1) fehlschlägt.

    Wenn du willst kannst du aber natürlich ne eigene malloc Implementierung schreiben die nen Haufen retries macht mit ein bisschen sleep() dazwischen. Und dann nach einer bestimmten Zeit, wenns bis dahin immer noch nicht geklappt hat, einfach abort() aufruft. Dann musst du den Returnwert nicht mehr prüfen 😉

    oh oh, das klingt ungemütlich. Wenn ich C programmiere, sieht meine malloc Implementierung in pseudo-code so aus:

    void* xmalloc (size_t n) {return malloc(n) or abort ("malloc failed");}
    

    (abgeguckt von git und anderen)

    In C++ ignoriere ich einfach bad_alloc() und wünsche mir, dass niemand jemals catch(std::exception) oder catch(...) macht.
    Das ganze bad_alloc()-exception-Konzept ist IMHO für den Eimer.


Anmelden zum Antworten