Warum scheint durchgesickerter Speicher Kernel_task zugeordnet zu sein, und warum kann OS X ihn daher nicht in den Garbage Collection sammeln

Mir wurde zuvor gesagt, dass ein Zeichen dafür, dass eine Anwendung ein Speicherleck kernel_taskhat, ein großer Speicherbedarf ist, der normalerweise in der Größenordnung von Gigabyte liegt. Wenn kextdiese Speichernutzung durch einen Fehler verursacht wurde, würden wir erwarten, dass eine Diskrepanz zwischen dem zugewiesenen Speicher und den erwarteten zugewiesenen angezeigt wird, dh

diff <(kextstat|tr -s ' ' | cut -d ' ' -f 5) <(kextstat| tr -s ' ' | cut -d ' ' -f 6) 

würde etwas anderes als die Wörter „Wired“ und „Name“ zurückgeben.

Während ich meine Diplomarbeit schreibe, habe ich festgestellt, dass das Ändern eines PDFs, während es in der Vorschau geöffnet ist, oft zu schlimmen Dingen führt: Der Speicherverbrauch von kernel_taskkann gelegentlich auf acht Gigabyte und mehr anwachsen. Wenn ich die Vorschau beende, kehrt sie sofort zum Normalzustand zurück . Offensichtlich stimmt also etwas nicht – und die Vorschau verliert unter diesen Bedingungen Speicher.

Also, meine Frage ist folgende: Wenn ich weiß, dass ein Prozess durch eine plötzliche und unerwartete Zunahme des Footprints von ram durchgesickert ist kernel_task, warum kann OS X dann nicht wissen, dass etwas schief gelaufen ist. Wenn das Beenden von Preview meinen fehlenden malloc()Speicher wiederherstellt, warum führt Darwin dann nicht automatisch eine Garbage Collection für mich durch?

Habe ich ein grundlegendes Missverständnis darüber, wie die Speicherverwaltung funktioniert?

BEARBEITEN : (15.9.15)

Hier ist eine Demonstration dessen, wovon ich spreche. Zunächst bemerke ich eine hohe Speicherauslastung durch kernel_task(Hinweis: Die Vorschau ist geöffnet, nur sichtbar am unteren Rand des Aktivitätsmonitors und verwendet 333 MiB RAM):

Hohe Kernel-Speicherauslastung

Lassen Sie uns nach den hilfreichen Bemerkungen von Ashley unten herausfinden, wie viel jeder Kext verwendet:

$ kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

...
...
...
   1249280 com.apple.driver.DspFuncLib
   1769472 com.apple.nvidia.driver.NVDAGK100Hal
   2629632 com.apple.nvidia.driver.NVDAResman
   6184960 com.apple.driver.AirPort.Brcm4360
$

Also keine große Menge. Meine Maschine hat sowohl diskrete als auch integrierte GPUs; Ihre Treiber verwenden nur wenige MiB kabelgebundenen RAM. Lassen Sie uns auf meine Vermutung Vorschau beenden und schauen, was mit dem Speicherbedarf von passiert kernel_task:

Das Töten der Vorschau hilft den Dingen

Die Vorschau ist weg und der Speicherbedarf des Kernels ist dramatisch gesunken. Es gibt immer noch keine Hinweise auf eine Änderung der Verwendung von kext: Die Ausgabe des obigen Befehls ist unverändert.

Bearbeiten : Fehler gemeldet als Nr. 22701036. Ich warte immer noch auf eine Antwort von Apple. Es gibt nichts besonders Interessantes, wenn Sie den Prozess in ActivityMonitor untersuchen, aber vielleicht übersehe ich etwas.

Ich bin wegen zweier Dinge verwirrt – könnten Sie das klären? 1) Ich denke, Ihr diffBefehl vergleicht die Spalten Sizeund aus der Ausgabe. Ich stimme zu, dass dies "zugewiesener Speicher" ist, aber ich glaube nicht, dass "erwartet wird, dass er zugewiesen wird" ( beschreibt es als "Die Anzahl der verdrahteten Bytes des Kernelspeichers, die der kext belegt"). 2) Sehen Sie die Diskrepanz zwischen und wenn Sie das Problem mit der Vorschau haben? WiredkextstatSizeWiredman kextstatSizeWired
1) Sie haben Recht - ich vergleiche die Elemente in Size und Wired from kextstat. Mein Verständnis ist, dass, wenn ein Kext leckt, die zugewiesenen Bytes und die, von denen der Kernel weiß, dass sie zugewiesen sind , unterschiedlich sind. In diesem Fall habe ich das dort eingefügt, um zu zeigen, dass ich keinen undichten Kext habe – also 2) tritt dies nicht auf, wenn die Vorschau RAM frisst. Stattdessen kernel_taskwächst viel. Ich werde versuchen, dieses Problem nachzustellen und ein Foto zu machen :-).
Vielen Dank! Warten Sie eine Sekunde: Ich schreibe nur eine Antwort, die helfen könnte.

Antworten (2)

Der Kern von OS X ist keine Garbage Collection; Die libkern C++ Runtime von IOKit erfordert, dass Entwickler ihren eigenen Speicher verwalten.

Mac-Speicherverwaltung

Von Wie funktioniert die Speicherverwaltung in Mac OS X?

Apple dokumentiert die niedrigsten Ebenen des Mach-Kernels und des virtuellen Speichersubsystems ziemlich gut im Web als Teil seiner Entwicklerdokumentation.

Da dieser Kernel von der Carnegie Mellon University entwickelt wurde, können Sie ganz einfach Dutzende von Artikeln finden, die ihn beschreiben.

Andere Quellen

Müllabfuhr

Garbage Collection existiert auf der Benutzer- oder Anwendungsebene. Auch auf dieser Ebene hilft Garbage Collection nur, wenn die Anwendung alle Ansprüche auf den Speicher freigegeben hat. Eine zirkuläre Abhängigkeit kann die Garbage Collection verhindern. Die Müllabfuhr selbst ist ein sich entwickelndes Forschungsgebiet und es ist schwierig, es richtig zu machen .

Melden Sie Fehler und Speicherlecks

Fehler in OS X führen zu Speicherlecks. Angesichts der Größe der Codebasis ist dies fast sicher.

Bitte melden Sie reproduzierbare Fehler direkt an Apple . Jeder Fehlerbericht hilft, und vielleicht hilft Ihr Beispiel den Apple-Ingenieuren dabei, die Ursache zu finden.

Das ist enttäuschend, aber zweifellos richtig. Ich habe den Fehler an Apple gemeldet – ich finde ihn einfach nur nervig!
Bitte teilen Sie die Fehlernummer als Bearbeitung Ihrer Frage mit. Andere, die Ihre Frage hilfreich finden, können dann doppelte Fehler melden, die Ihr Original erwähnen. Ein Haufen verwandter Fehler wird dazu beitragen, mehr Entwicklungszeit zu rechtfertigen.

Hier ist meine Vermutung, vorausgesetzt, Ihr Mac hat eine integrierte GPU (z. B. Intel Iris Graphics).

Wenn Sie Ihre Abschlussarbeit in der Vorschau geöffnet haben, wird der Grafikkartenspeicher verwendet, um das Bild ("Textur") des Vorschaufensters und möglicherweise auch einige nicht auf dem Bildschirm angezeigte, aber dekodierte Seiten der Abschlussarbeit zu speichern.

Bei einer integrierten Grafikkarte befindet sich der Videospeicher tatsächlich (teilweise?) im System-RAM, der von CPU und GPU gemeinsam genutzt wird. Bei einigen integrierten Grafikkarten wird die Menge des verwendeten System-RAM dynamisch zugewiesen (siehe Apple HT204349 ).

Ich vermute, dass Sie zeitweise einen Fehler im Grafikkartentreiber und/oder in der Vorschau sehen, der den Systemspeicher nicht korrekt freigibt, wenn die Vorschau Ihre Abschlussarbeits-PDF neu lädt. (Dieser Fehler wird jedoch durch OS X/den Treiber behoben, der den Speicher beim Beenden der Vorschau korrekt freigibt.)

Sie können versuchen, sich die Ausgabe von anzusehen kextstatund zu sehen, ob die Zahlen in der SizeSpalte steigen, wenn das Problem auftritt. Meine Theorie ist, dass die von Ihnen erwähnte Erhöhung um 8 GB auf den Grafikkartentreiber zurückzuführen ist.

Der folgende Befehl (aus einem Kommentar zu dieser verwandten und interessanten Antwort ) sortiert die Ausgabe von kextstat, um leichter erkennen zu können, welcher Kext den meisten Speicher verwendet (obwohl dies nach Spalte sortiert istWired ... es gibt eine ähnliche, einfachere Beschwörung). antworten Sie mit einer Erklärung, wenn Sie dies optimieren möchten).

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n
Gute Vermutung - und vielen Dank für eine nützliche, sortierte Ausgabe von kextstat. Allerdings sieht es immer noch nicht so aus, als ob es wirklich so wäre: Während des Preview-Verschluckens blieb der Speicherbedarf von com.apple.nvidia.driver.*unverändert. Ich habe meine Frage bearbeitet, um dies widerzuspiegeln.