Is there a way to get the Heap Size programmatically in Servoy. For instance, in the developer (and many other Java apps for that matter) you can see a display of the current heap size usage and usually there is an option to run garbage collection as well. Just curious if we can obtain that info. It would be helpful in bug reporting for instance.
Not programmatically but in Smart Client you can get a memory usage graph by selecting the menu “About Servoy Client…”, to run the garbage collector simply click on the graph.
In the Smart client, you can have a look at the “Help > About…” window, which will give you a graphical representation of memory consumption, with the allocated and used memory.
Clicking on the graph actually run the Garbage collector.
If you want programatical access though, you can use Java in Servoy:
var runtime = java.lang.Runtime.getRuntime();
application.output("Max memory: "+runtime.maxMemory() / 1024); // Maximum heap
application.output("Total memory: "+runtime.totalMemory() / 1024); // Heap allocated
application.output("Before GC:");
application.output("Free memory: "+runtime.freeMemory() / 1024); // Not used in the heap
application.output("After GC:");
runtime.gc(); // Force the Garbage Collector to run immediately
application.output("Free memory: "+runtime.freeMemory() / 1024);
Nice tip Patrick!
I think I will use it after printing large files with Jasper to release some memory, I noticed that sometimes memory is not released correctly.
Then there’s something wrong with Jasper: after a big jasper print sometimes clients do not release memory. I see many of them using almost 300MB and that’s not good when they are running on Citrix because they limit the max number of citrix sessions per server.
but calling gc() wouldn’t help you there.
Its not that the clients memory is going down… Its just that the internal memory heap that java uses is cleaned up.
The os won’t get any more free memory, so this:
didn’t know that these options where now in the vm (i think these options where there from java 5 on)
I guess in the default settings you will not really notice it because thats a quite large thing that it has to be more the 70% and then it shrinks.
so if you have 100MB heap and then you use 28MB it will shrink to +/-98 … So i guess thats why i almost have never seen it…
i guess you have to tweak those options then for example to:
Hi and sorry to have opened this can of worm, I should have said to not call gc() - it’s a process intensive operation that takes time, and Java is supposed to call garbage collecting at the best convenient time anyway.
That being said, in the context of Jasper in particular, it is a memory hog, and I also suspect that there are memory leaks, I know there are some issues in the iText library for example.
What could be done maybe would be to launch Jasper in a different process and kill this process when done - someone already asked me to patch the plugin so that it would do that with a simple parameter switch, but I have other (better) stuff to do (like maintaining VelocityReport for example, ah ah) -, or maybe use Jasper server to create reports…
After some serious testing I’m able to reproduce a huge memory issue with Jasper Reports.
We are printing a large jasper report in Smart Client (40 pages, 6-10 images per page), the client is set to start with 64MB and is allowed to grow to 256MB of heap memory. During normal solution usage the heap always stays between 40MB and 75MB depending on what the user is doing, when we start generating the report it grows up to 94MB at max; the real problem is that once the report is done and it’s showed in Jasper Viewer if the user start previewing the pages or sends the report to the printer (Mac or Win) or the Preview app (in MacOS only) the heap usage grows up to the max (256MB). I guess that the Viewer has to load everything in RAM so although it seems just too much memory usage for a 7MB PDF file but I guess that everything is uncompressed or raw when in memory.
The real problem is that after the user closes the Jasper Viewer and resume normal work that heap memory is not released. Forcing the GC to run 3-4 times or more in a row (by clicking the memory graph or running the JS code that Patrick posted) does release the memory and the heap usage drops as low as 40MB as it should be.
What I’m doing right now to workaround the issue is to pass this params to the client JNLP file:
-XX:MaxHeapFreeRatio=10
-XX:MinHeapFreeRatio=10
and to run the GC collector 6 times in a row AFTER the Jasper report viewer is closed, this is the only way I’ve found to lower the Heap usage and give back memory to the OS.
I know it’s not good practice but I haven’t been able to find a better way.
This workaround is ok for medium reports likes this but when generating big ones (70+ pages, full of images) 256MB of ram for the smart client is just not enough, what could I do?
Should I create a case for this or is just beyond your control?
I don’t think this is something Servoy or a plugin can anything do about. What you could do is generate reports on the server that has loads of memory (and only generate 1 at the same time…)
Virtualizers are not helping in this case, we do use them to spool to a swap file but the Jasper viewer is claiming all that memory anyway when scrolling the pages or printing.
this is not a solution, but a workaround,
you can try to print to pdf with jasper, than you CAN use the virtualizer, because at first, the pdf is created ON the server, after that it get’s auto streamed to servoy-client, and open it with your default pdf viewer.
Thanks Harjo, I will test your workaround, we just need to make sure that font embedding does work when Jaspers generate the PDF.
I’m also considering Jasper Server but it looks like an overkill.