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).
Managed to isolate it thru a sample program as below :
import com.aspose.cells.*;
public class Sample
{
public static void main(String[] args) throws Exception
{
new Thread("MemoryWatch") {
public void run() {
for (int i =0; i<20; i++)
{
Runtime rt = Runtime.getRuntime();
rt.gc();
int totalMB = (int)(rt.totalMemory()/1024/1024);
int freeMB = (int)(rt.freeMemory()/1024/1024);
System.out.println("Total= " + totalMB + " MB, free= " + freeMB + " MB");
try{Thread.sleep(1000);}catch(Exception e) {e.printStackTrace();}
}
}
}.start();
convertFile("Bad.xlsx");
}
public static void convertFile(String fileName) throws Exception
{
System.out.println("Converting : " + fileName);
Workbook workbook = new Workbook(fileName);
workbook.save(fileName + ".pdf");
System.out.println("Done. Output : " + fileName + ".pdf");
workbook = null;
}
}
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
I am basically just converting an excel file to pdf using Aspose library, since the conversion code is in a separate method I believe once the method gets executed, shouldn't all memory allocated while executing that method and while creating instances of objects inside that method free up once the method completes ?? Apparently that's not happening here.
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 with this file.
There may or may not be a memory leak in Aspose implementation but is there a way to prevent it from my code ?
Thanks, Rajiv
Update-3
CELLSJAVA-42597 is marked as resolved (won't fix) now. Please refer to this topic in Aspose.Cells forum for more information.
Update-2
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
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
Update-1
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 18.3 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) not happening with Aspose.
Note: I am working as Developer Evangelist at Aspose