Я назначил нашей Java программе 2 ГБ памяти. В течение часов работы определенного потока память постоянно и линейно увеличивается, пока Kubernetes не убьет ее, потому что она достигает установленного мною лимита в 2 ГБ. Конечно, мы думали об утечке памяти, но мы постоянно видим что-то подобное в журнале g c:
[7406.381s][info][gc] GC(8326) Pause Full (System.gc()) 130M->65M(214M) 157.995ms
- Поскольку память увеличивается линейно, в то время как эти журналы указывают, что память кучи не увеличивается, бесполезно ли исследовать утечки памяти?
- Что может быть другими вероятными причинами увеличения памяти?
Некоторая справочная информация:
Нет журналов, в которых говорится, что контейнер был остановлен или убит. В k8s также нет событий (однако "restarts" = 1). Приведенная выше строка журнала была последней строкой журнала, прежде чем мы увидели (в Graylog), что Spring Boot / Tomcat запускается (следовательно, он должен быть перезапущен). Мы видим, что это происходит именно в то время, когда граф памяти достигает линии 2 ГБ в Grafana. Без Графаны потребовалось бы некоторое время, прежде чем мы поняли, что это что-то связанное с памятью.
Kubernetes deploy yml part:
spec:
template:
spec:
containers:
- name: ... (omitted)
resources:
limits:
cpu: 1200m
memory: 2Gi
requests:
cpu: 50m
memory: 50Mi
Последняя строка Dockerfile:
ENTRYPOINT ["java", "-Xmx2G", "-verbose:gc", "-jar", "/backend.jar"]
где "-verbose: g c" вызывает строки журнала, подобные приведенной выше строке.
Требуется некоторое время, чтобы воспроизвести проблему, но мы сделали это пару раз.
Мы используем Java 11.