2017-03-25 1 views
1

Ich habe einen Java-Prozess, der eine native Bibliothek verwendet. Diese native Bibliothek ist ziemlich ressourcenintensiv und wird eine Menge RAM ausgeben. Darüber hinaus wird es für einige Eckfälle meinen gesamten Speicher vollständig beanspruchen und mein System vollständig einfrieren.Einstellung JNI und Unterprozessspeicher Grenze

Es wäre gut, wenn die Anwendung gerade in diesen komischen Ecken Fällen abgestürzt wäre. Aber wenn eine Ausnahme ausgelöst werden kann, wäre das noch besser. Gibt es eine Möglichkeit, ein Speicherlimit für Aufrufe an diese JNI-Bibliothek und für die Ausführung von Teilprozessen festzulegen?

Ich habe versucht, ulimit -v unter Linux, aber es hat nicht funktioniert. Idealerweise hätte ich gerne eine portablere Lösung, da das Programm auch auf anderen Plattformen laufen muss.

+0

Es gibt keine wirklichen Lösungen, die mir bekannt sind. Im besten Fall, wenn Sie genug darüber wussten, wie diese Bibliothek funktioniert, können Sie die Speicherauslastung in irgendeiner Weise beeinflussen und Fehler an ihren 'malloc()' -Aufrufen zurückgeben, aber von Ihrer Beschreibung des Verhaltens wird diese Bibliothek wahrscheinlich nicht betroffen sein Ein solcher Fehler kommt gut zurück, was sowieso zu Abstürzen oder beschädigten Daten führt. Eine portable plattformübergreifende Lösung wäre noch schwieriger. IMO spielt eine JVM mit LD_PRELOAD oder DLL-Injektion und spielt gleichzeitig mit Feuer und Benzin. Eine sich schlecht benehmende 3rd-Party-Bibliothek fügt Antimaterie hinzu. –

Antwort

1

Es gibt sicherlich keine tragbare Lösung. Die Beschränkung der Ressourcennutzung durch den aktuellen Prozess und untergeordnete Prozesse kann nur vom Betriebssystem durchgeführt werden. Das macht es unbedingt plattformspezifisch und nicht portabel.

Sie haben versucht, ulimit und das funktioniert nicht für Sie. (Ich stelle mir das vor, weil die Grenzen pro Prozess sind) Eine andere Alternative sind Linux Control Groups (Cgroups).

In beiden Fällen sind ulimit und cgroups nicht tragbar, und Sie können sie außerhalb einer JVM festlegen oder verwalten.

+0

* Die Ressourcenverwendung im aktuellen Prozess und untergeordneten Prozessen kann nur vom Betriebssystem eingeschränkt werden. * Und das ist auch prozessweit. Ich kenne keine Möglichkeit, die Ressourcennutzung durch eine * Bibliothek * einzuschränken, die in einen Prozess eingebunden ist. –

+0

Ich meinte "durch den aktuellen Prozess ...". Es gibt keine Möglichkeit, einzuschränken, was eine native Bibliothek innerhalb eines Prozesses tun kann. –

+0

Kein * einfacher * Weg. Wie ich bereits in meinem Kommentar erwähnt habe, ist es möglich, Speicherverwaltungsfunktionen wie "malloc()" einzubinden, zu bestimmen, woher der Aufruf kommt und den Speicherverbrauch der Bibliothek auf diese Weise zu begrenzen. Das ist allerdings ein hässlicher Hack, und die Einmischung in einen Java-Prozess ist von Anfang an voller Gefahren. Und das setzt auch voraus, dass die Bibliothek sich gut verhält, wenn das zwischengelagerte 'malloc()' 'NULL zurückgibt, wenn es das spezifizierte Limit erreicht. –

0

Die JNI-Bibliothek wird in den JVM-Prozess geladen. Daher können Sie keine speziellen Speicherbeschränkungen nur für den JNI-Teil anwenden. Nur das Erstellen eines zweiten Prozesses würde dies ermöglichen, aber das würde eine prozessübergreifende Kommunikation zwischen Ihrem Haupt-Java-Prozess und dem zweiten Prozess erfordern, der den JNI-Teil enthält.

Die Begrenzung der Speichernutzung ist jedoch eine Aufgabe des Betriebssystems - daher gibt es keine plattformunabhängige Lösung.

Die einzige saubere Möglichkeit sehe ich darin, die Bibliotheksquellen zu modifizieren (hoffentlich sprechen wir über eine Open-Source-Bibliothek?) Oder die verwendete Bibliothek so zu konfigurieren, dass die Speicherbelegung begrenzt wird (sofern dies unterstützt wird)).