Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory and Handle leak when terminating SVGGenerator #605

Open
ssindelar opened this issue Mar 1, 2021 · 0 comments
Open

Memory and Handle leak when terminating SVGGenerator #605

ssindelar opened this issue Mar 1, 2021 · 0 comments

Comments

@ssindelar
Copy link

Hallo.

We use the chart export a lot. In the past we had problems with dying phantomjs instances, so we changed our code to start phantomjs, do the export and than destroy the phantomjs instance. This worked fine. But lately we updated from oracle jdk8 to openjdk 11 (amazon coretto) and noticed that on some customer systems the application encountered OutOfMemory Errors despite having still a lot of memory left. After a lot of searching it turned out the application leaked handles, which results in an OOM when the OS can't provide a handle.

After a lot of searching and debugging I found that the SVGGenerator was the main cause. Because we start/stop the phantomjs instance with each export we leak 4 handles. There are two bugs in ne SVGGenerator

  1. When destroy() is called, the phantomjs process gets killed but the 3 Streams (Input, Output and Error) are not closed. This causes the 3 handles of the stream to leak. Process streams need to be closed after the process has ended. See the jdk internal class jdk.internal.jline.internal.TerminalLineSettings in the waitAndCapture-method for an example. The reason the streams are not closed is when Process.destory() is called because there could still be data in the streams that could be read afterwards. Changing this would break backward compatibility.
  2. Each time a new PhandomJS instance is created a shutdown hook is registered to kill it when the applications stops. This is a good practise but the problem is the hook is never removed. Therefore which start of phantomjs an other hook is created. The hook needs to be removed when destroy() is called. This causes the process handle to leak. Also this causes a small memory leak of the objects (Thread, Process, ...) involved.

It seems between oracle jdk 8 and openjdk 11 the behaviour around leaks changed. Also it may be OS dependent because on my system I wasn't able to reproduce the leak but we implemented a workaround that closes the handles and doesn't add a shutdown hook and this fixed the leaks on the customer systems.

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant