Aspose Cells not releasing memory after processing a particular file (ECDCTS-5446)

Hi,

I am facing a strange issue wherein a piece of code never releases the memory after finishing. The behavior is machine specific though, issue is seen on my VM running on Windows Server 2012-R2 (64-bit) with Intel Xeon CPU E5-2699, but doesn’t occur on my laptop running on Windows10 (64-bit) with Intel Core i7-7820HQ CPU. Both are running on latest version of Java 1.8 (64-bit).

Please find the sample program attached. I am basically just converting an excel file to pdf in a simple two line code which is in a separate method, I am calling it from Main, I believe once the method gets executed, it should free up the used memory, but it doesn’t happen in this case. I have created a separate thread from Main to watch the memory usage, I can see there that even after completion of processing, the memory usage never comes down. It happens only for this excel file though, for all other excel document memory usage goes up during processing but later comes down once done, something strange in this file.

Bad environment

java -Xmx512m -Xms512m Sample
Converting : Bad.xlsx
Total= 491 MB, free= 490 MB
Total= 491 MB, free= 475 MB
Total= 491 MB, free= 469 MB
Total= 491 MB, free= 399 MB
Total= 459 MB, free= 282 MB
Total= 466 MB, free= 240 MB
Total= 479 MB, free= 270 MB
Total= 489 MB, free= 282 MB
Done. Output : Bad.xlsx.pdf
Total= 494 MB, free= 295 MB
Total= 498 MB, free= 298 MB
Total= 497 MB, free= 297 MB
Total= 500 MB, free= 300 MB
Total= 499 MB, free= 299 MB
Total= 501 MB, free= 302 MB
Total= 500 MB, free= 301 MB
Total= 503 MB, free= 303 MB
Total= 502 MB, free= 302 MB
Total= 504 MB, free= 304 MB
Total= 503 MB, free= 304 MB
Total= 505 MB, free= 306 MB

Good environment :

java -Xmx512m -Xms512m Sample

Converting : Bad.xlsx
Total= 491 MB, free= 488 MB
Total= 491 MB, free= 475 MB
Total= 491 MB, free= 470 MB
Total= 479 MB, free= 432 MB
Total= 487 MB, free= 441 MB
Done. Output : Bad.xlsx.pdf
Total= 494 MB, free= 456 MB
Total= 493 MB, free= 455 MB
Total= 496 MB, free= 458 MB
Total= 495 MB, free= 457 MB
Total= 498 MB, free= 460 MB
Total= 497 MB, free= 459 MB
Total= 500 MB, free= 461 MB
Total= 499 MB, free= 461 MB
Total= 501 MB, free= 463 MB
Total= 501 MB, free= 462 MB
Total= 503 MB, free= 464 MB
Total= 502 MB, free= 464 MB
Total= 504 MB, free= 466 MB
Total= 503 MB, free= 465 MB
Total= 505 MB, free= 467 MB

Output completed (21 sec consumed) - Normal Termination

Sample.zip (428.7 KB)

Thanks,
Rajiv

@rajivrp

Thanks for using Aspose APIs.

We recommend you to read the following article that could help you resolve memory issue.

Besides, you must use our most recent version because we have also done enhancements regarding memory consumption. The most recent version is 18.4 which is about to be released in couple of days. But you can try it on Aspose.Cells for Java 18.3.9 as well.


It could also be the issue of Java heap probably and not the issue of Aspose.

Can you replicate the issue without Aspose? For example, in your thread, you can create 500 MB array of bytes and let the memory heap grow until it shows up as in your output and then free the 500 MB memory by assigning null to byte array and your output should reflect that heap memory has lowered or released which (in your words) is not happening with Aspose.

Hi Shakeel,

I am unable to replicate the issue without Aspose, if I create a large byte array as you suggested, memory usage number goes up in my program, and comes down as soon as it is released, and comes down 100% to the same level as before.

I also tried opt.setMemorySetting(MemorySetting.MEMORY_PREFERENCE) as above Aspose post suggests, but that didn’t help either, Aspose never releases the memory after processing this file, it’s reproducible with Aspose Cells for Java 18.4.

It looks like an Aspose bug to me.

Updated_sample.zip (1.2 KB)

Thanks,
Rajiv

@rajivrp

Thanks for your runnable sample code and using Aspose APIs.

We executed your code and got the following output. We have logged this issue in our database for further investigation and analysis. Once, we will have some news for you, we will update you asap.

This issue has been logged as

  • CELLSJAVA-42597 - Aspose.Cells not releasing memory after processing a particular file

Console Output:

Total= 123 MB, free= 122 MB
Total= 123 MB, free= 122 MB
-----------------------------
Entering consumeMemory 
-----------------------------
Total= 123 MB, free= 105 MB
Total= 480 MB, free= 229 MB
Total= 575 MB, free= 324 MB
Total= 575 MB, free= 324 MB
Total= 575 MB, free= 324 MB
Total= 575 MB, free= 324 MB
Total= 574 MB, free= 323 MB
-----------------------------
Exiting consumeMemory 
-----------------------------
Total= 574 MB, free= 574 MB
Total= 573 MB, free= 573 MB
-----------------------------
Processing : Bad.xlsx
-----------------------------
Total= 574 MB, free= 564 MB
Total= 575 MB, free= 559 MB
Total= 576 MB, free= 539 MB
Total= 732 MB, free= 689 MB
Total= 725 MB, free= 646 MB
Total= 738 MB, free= 640 MB
Total= 752 MB, free= 621 MB
Total= 991 MB, free= 726 MB
Total= 987 MB, free= 824 MB
Total= 953 MB, free= 801 MB
-----------------------------
Done. Output : Bad.xlsx.pdf
-----------------------------
Total= 987 MB, free= 841 MB
Total= 953 MB, free= 806 MB
Total= 984 MB, free= 837 MB
Total= 953 MB, free= 806 MB
Total= 980 MB, free= 833 MB
Total= 953 MB, free= 806 MB
Total= 977 MB, free= 831 MB
Total= 953 MB, free= 806 MB
Total= 974 MB, free= 827 MB

Hi Shakeel,

You seem to have run java program without passing memory hot-spot parameters explicitly, so the process memory keeps changing. You need to try it like this to get a better idea about this behavior :

java -Xmx512m -Xms512m Sample

Thanks,
Rajiv

@rajivrp

Now I get this output. Also attached the Eclipse Run Configuration Screenshot for your reference.

Console Output:

Total= 491 MB, free= 490 MB
Total= 491 MB, free= 490 MB
-----------------------------
Entering consumeMemory 
-----------------------------
Total= 491 MB, free= 471 MB
Total= 491 MB, free= 240 MB
Total= 491 MB, free= 240 MB
Total= 491 MB, free= 240 MB
Total= 491 MB, free= 240 MB
Total= 491 MB, free= 240 MB
Total= 491 MB, free= 240 MB
-----------------------------
Exiting consumeMemory 
-----------------------------
Total= 491 MB, free= 490 MB
Total= 491 MB, free= 490 MB
-----------------------------
Processing : Bad.xlsx
-----------------------------
Total= 491 MB, free= 475 MB
Total= 491 MB, free= 450 MB
Total= 444 MB, free= 361 MB
Total= 463 MB, free= 311 MB
Total= 475 MB, free= 321 MB
Total= 488 MB, free= 270 MB
Total= 492 MB, free= 340 MB
-----------------------------
Done. Output : Bad.xlsx.pdf
-----------------------------
Total= 494 MB, free= 348 MB
Total= 498 MB, free= 352 MB
Total= 497 MB, free= 351 MB
Total= 499 MB, free= 353 MB
Total= 499 MB, free= 353 MB
Total= 501 MB, free= 355 MB
Total= 500 MB, free= 354 MB
Total= 503 MB, free= 357 MB
Total= 502 MB, free= 356 MB
Total= 504 MB, free= 358 MB
Total= 503 MB, free= 357 MB
Total= 505 MB, free= 359 MB

Screenshot:

Ok great, so this makes it very clear to understand that there is a bug in Aspose Cells. Before processing this file the free memory was 490 MB, and after completing the processing it is ~359 MB, and it stays like that forever.

Will be waiting to hear on CELLSJAVA-42597.

Regards,
Rajiv

@rajivrp

Thanks for using Aspose APIs.

You are right. We have recorded your analysis as well.

Sure. We will keep you informed with any update available regarding this issue. Thank you and have a good day.

Hi Shakeel,

CELLSJAVA-42597 bug status has been updated to ‘Resolved’ … is the new build with this fix available already ?

Thanks,
Rajiv

@rajivrp,

We did evaluate your issue in details.
Well, it is not the bug of Aspose.Cells. For Bad.xlsx, there is a character that cannot be rendered by the specified font (Calibri) for value of cell A1634. For such situation, we have to search other fonts to get one which can render the character fine. For performance consideration, we cache all parsed fonts as static cache so it can be reused by other rendering processes. For different machines, the installed fonts and their sequence might be different, so the searched and cached fonts may be different and the memory cost will be different too. To release the memory used by the font(s) cache, you may use:
e.g
Sample code:

FontConfigs.setFontExclusiveSources(null);

In this way the font cache will be clear. However, you should make such decision carefully, because if there are many other workbooks that need to be rendered later and use different fonts, clearing the cache will cause much more time cost for the rendering process for sure.

Hi Amjad,

Thanks very much for explanation. I am able to overcome the issue with the API you suggested. Whenever FontConfigs.setFontExclusiveSources(null) is called, memory gets released immediately, so that’s a good news.

I am curious to know more about this API if you can share some more technical details as to what exactly it does internally. What will happen if it finds another font that can render that character ? E.g. I have just learnt that ‘Segoe UI Emoji’ font can render that character, so case if that font is installed will Aspose still maintain the cache for all fonts that it has scanned until checking ‘Segoe UI Emoji’ OR it will release the cache once the right font is found ??

Also can you pls confirm that there is no other functional impact of calling this API other than higher processing time for future similar files ??

Regards,
Rajiv

@rajivrp,

Thanks for sharing your concerns.

We will evaluate and provide more details soon.

@rajivrp

Thanks for using Aspose APIs.

For such kind of situation (it is just the situation for Bad.xlsx), we will maintain the cache for all fonts that have been scanned because those fonts may be used by other contents later. For example, before scanning ‘Segoe UI Emoji’ font, “Arial” font may be parsed, it cannot be used by this character or this cell, but maybe there are some other cells which have been specified to use “Arial” font. For performance consideration, we should not remove the parsed info of “Arial” and re-parse it again and again.

Yes, we can confirm, the only impact is the time cost for parsing fonts repeatedly.

Alright … thank you !

Regards,
Rajiv