La seule véritable option est (malheureusement) de mettre fin à la JVM dès que possible.
Puisque vous ne pouvez probablement pas modifier tout votre code pour détecter l'erreur et répondre. Si vous ne faites pas confiance au OnOutOfMemoryError
(Je me demande pourquoi il ne devrait pas utiliser vfork qui est utilisé par Java 8 et qui fonctionne sous Windows), vous pouvez au moins déclencher un vidage de tas et surveiller ces fichiers en externe :
java .... -XX:+HeapDumpOnOutOfMemoryError "-XX:OnOutOfMemoryError=kill %p"
Après avoir expérimenté cela pendant un certain temps, voici la solution qui a fonctionné pour nous :
- Dans la JVM générée, attrapez un
OutOfMemoryError
et quittez immédiatement, en signalant la condition de mémoire insuffisante avec un code de sortie au contrôleur JVM. - Dans la JVM générée, vérifiez périodiquement la quantité de mémoire consommée du
Runtime
actuel . Lorsque la quantité de mémoire utilisée est proche de critique, créez un fichier d'indicateur qui signale la condition de mémoire insuffisante à la JVM du contrôleur. Si nous récupérons de cette condition et quittons normalement, supprimez ce fichier avant de quitter. - Une fois que la JVM de contrôle a rejoint la JVM forkée, elle vérifie le code de sortie généré à l'étape (1) et le fichier d'indicateur généré à l'étape (2). En plus de cela, il vérifie si le fichier
hs_err_pidXXX.log
existe et contient la ligne "Out of Memory Error". (Ce fichier est généré par Java en cas de plantage.)
Ce n'est qu'après avoir mis en œuvre toutes ces vérifications que nous avons pu gérer tous les cas où la JVM forkée manquait de mémoire. Nous pensons que depuis lors, nous n'avons manqué aucun cas où cela s'est produit.
Le drapeau Java -XX:OnOutOfMemoryError
n'a pas été utilisé à cause du problème de fourche, et -XX:+HeapDumpOnOutOfMemoryError
n'a pas été utilisé car un vidage de tas est plus que nécessaire.
La solution n'est certainement pas le morceau de code le plus élégant jamais écrit, mais a fait le travail pour nous.