En mode sans déchet, Log4j2 réutilise les objets LogEvent. Pour empêcher plusieurs threads de modifier le même LogEvent en même temps, chaque thread a son propre LogEvent. Ceci est implémenté avec ThreadLocal. ThreadLocals Un point clé de ThreadLocals est que tout ce qui est mis en eux reste là jusqu'à ce qu'il soit explicitement retiré ou que le thread meurt. Même s'il n'y a pas d'autres références à LogEvent, il ne sera pas collecté car le ThreadLocal a toujours une référence, et les threads sont des racines GC.
Les conteneurs d'applications Web chargent souvent une application Web dans un chargeur de classe personnalisé. Cela permet d'arrêter et de recharger différentes versions d'une application Web sans redémarrer le conteneur d'applications Web. Toutefois, si quelque chose a toujours une référence à une classe de la version précédente de l'application Web, cette classe et toutes les classes associées, y compris le chargeur de classes personnalisées, ne peuvent pas être récupérées.
Quand cela pourrait-il se produire? Lorsque le conteneur de l'application Web dispose d'un pool de threads partagé entre les applications Web et non vidé lorsque l'application Web est rechargée. Les threads du pool ont toujours des références ThreadLocal à un objet LogEvent et à une classe de la version précédente de l'application Web. Cette classe ne peut donc pas être récupérée et vous avez une fuite de mémoire.
Conclusion Vous pouvez utiliser l'enregistrement gratuit des ordures dans les applications web si les deux conditions suivantes sont remplies:
- Les pools de threads ne sont pas partagées entre les applications Web
- Lorsqu'une application Web est rechargée, son pool de threads est également fermé et redémarré
Si les deux réponses ci-dessus sont vraies, je crois que vous pouvez configurer Log4j2 pour utiliser la journalisation sans déchet sans risque fuites de mémoire. Bien sûr, vous devrez faire preuve de diligence raisonnable et tester.