Dockerized spring boot app issue with Aspose.Words - OutOfMemoryError: Java heap space

spring boot application
maven build tool
aspose total (currently, trial edition)

The application takes pdf, word, excel and image files and converts them to .tiff. The java code for the converters is really simple so i doubt it will be a code problem.
The converter is executed using an http endpoint.

The application is deployed for testing in a linux vm using docker. I’m using “openjdk:11” as base image. The slim edition caused errors (related to fonts i think).

I’m using some test files as input and until now i have found the following cases in which the application fails to convert some files:

  1. Pdf to tiff conversion when the application receives 2 requests to convert 2 different pdf files to tiff.
    The request are sent about the same time using Postman, that is, the are two conversion processes
    run at the same time. This causes the following problem:
java.lang.OutOfMemoryError: Java heap space

[994.979s][warning][gc,alloc] http-nio-8080-exec-10: Retried waiting for GCLocker too often allocating 3210508 words
[994.991s][warning][gc,alloc] http-nio-8080-exec-10: Retried waiting for GCLocker too often allocating 4348682 words
2022-04-14 15:54:04.305 ERROR 1 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause

As a result, one pdf file may not be converted successfully.

PS The files get converted successfully and the application doesn’t throw an exception if i convert
them one by one

  1. Same case for the doc/docx to tiff converter.
    Running two conversion processes at the same time causes:
2022-04-15 14:49:44.305 ERROR 1 --- [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause

java.lang.OutOfMemoryError: Java heap space

PS The files get converted successfully and the application doesn’t throw an exception if i convert
them one by one

  1. Same case as 2) but for some reason i have got also this output (i didn’t change the code):
2022-04-15 15:14:01.230 ERROR 1 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause

java.lang.OutOfMemoryError: Java heap space
at java.desktop/java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75) ~[na:na]
at java.desktop/java.awt.image.SinglePixelPackedSampleModel.createDataBuffer(SinglePixelPackedSampleModel.java:242) ~[na:na]
at java.desktop/java.awt.image.Raster.createWritableRaster(Raster.java:1005) ~[na:na]
at java.desktop/java.awt.image.BufferedImage.getData(BufferedImage.java:1422) ~[na:na]
at javax.media.jai.RenderedImageAdapter.getData(RenderedImageAdapter.java:153) ~[jai-core-1.1.3.jar!/:na]
at com.sun.media.jai.codecimpl.TIFFImageEncoder.encode(TIFFImageEncoder.java:180) ~[jai-codec-1.1.3.jar!/:na]
at com.sun.media.jai.codecimpl.TIFFImageEncoder.encode(TIFFImageEncoder.java:137) ~[jai-codec-1.1.3.jar!/:na]
at com.aspose.words.internal.zzXlK.zzWPL(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.internal.zzXlK.zzWun(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.internal.zzZ23.zzWun(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.zzXBm.zzhl(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.zzXBm.zzWPL(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.zzyR.zzWPL(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.Document.zzD8(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.Document.zzWPL(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at com.aspose.words.Document.save(Unknown Source) ~[aspose-words-21.10-jdk17.jar!/:21.10.0]
at eu.company.asposeconverter.converter.WordToTiffConverter.runConverter(WordToTiffConverter.java:33) ~[classes!/:0.0.1-SNAPSHOT]
at eu.company.asposeconverter.service.AsposeService.convert(AsposeService.java:40) ~[classes!/:0.0.1-SNAPSHOT]
at eu.company.asposeconverter.controller.AsposeController.convert(AsposeController.java:26) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.17.jar!/:5.3.17]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.17.jar!/:5.3.17]
  1. Running only one conversation process at a time will output the same as in case 2)
    when i provide two specific doc files as input.

What should i do either to the spring boot application or the docker image/container?

In the production environment the application should be able to accept about 6-8 requests for conversion at the same time!

@stsakas Could you please attach your test input documents and your code? We will check the issue and provide you more information.

I would like to send the files in private. Should i send them to you in a PM?

@stsakas It is safe to attach documents in the forum. Only you and Aspose staff can download them.
Also, you can send the files via private message, just click my login and then press message button.

1016568_2016_37513.pdf (7.1 MB)

136680_2018_154074.docx (245.9 KB)

I can’t send the .doc file because the forum doesn’t support it.

Remember: The application is running using docker. Without docker, the application can successfully convert the .docx file i sent you.
As for the pdf, just make 3 copies of it and run three converters at the same time.

@stsakas Thank you for additional information. We will investigate your scenario and provide you more information.
Regarding DOC files, you can zip the documents and attach them as ZIP archive. Also, please attach your dockerfile, which might also be useful for testing.

dockerfiles.zip (753 Bytes)

Here are the docker files. They don’t have any special configuration.

How long will it take to check it out?

Thanks

Hi again.

I managed to get the same error by running the spring application without docker:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.desktop/java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
	at java.desktop/java.awt.image.SinglePixelPackedSampleModel.createDataBuffer(SinglePixelPackedSampleModel.java:242)
	at java.desktop/sun.awt.image.IntegerInterleavedRaster.<init>(IntegerInterleavedRaster.java:71)
	at java.desktop/sun.awt.image.IntegerInterleavedRaster.createCompatibleWritableRaster(IntegerInterleavedRaster.java:526)
	at java.desktop/sun.awt.image.IntegerInterleavedRaster.createCompatibleWritableRaster(IntegerInterleavedRaster.java:536)
	at com.aspose.words.internal.zzXYH.createCompatibleDestRaster(Unknown Source)
	at com.aspose.words.internal.zzYtY.zzXWe(Unknown Source)
	at com.aspose.words.internal.zzYtY.zzWPL(Unknown Source)
	at com.aspose.words.internal.zzYtY.filter(Unknown Source)
	at com.aspose.words.internal.zzWCy.zzWPL(Unknown Source)
	at com.aspose.words.internal.zzWrj.zzWPL(Unknown Source)
	at com.aspose.words.internal.zzWrj.zzD8(Unknown Source)
	at com.aspose.words.internal.zzWrj.zzWPL(Unknown Source)
	at com.aspose.words.internal.zzWrj.zzWPL(Unknown Source)
	at com.aspose.words.zz2E.zzZkv(Unknown Source)
	at com.aspose.words.zz2E.zzWPL(Unknown Source)
	at com.aspose.words.zzXBm.zzXKT(Unknown Source)
	at com.aspose.words.zzXBm.zzhl(Unknown Source)
	at com.aspose.words.zzXBm.zzWPL(Unknown Source)
	at com.aspose.words.zzyR.zzWPL(Unknown Source)
	at com.aspose.words.Document.zzD8(Unknown Source)
	at com.aspose.words.Document.zzWPL(Unknown Source)
	at com.aspose.words.Document.save(Unknown Source)

This error is thrown when trying to convert the 16470_2017_60417.doc file to tiff. So, no docker and no multiple converters running at the same time.

@stsakas,

Unfortunately, we cannot reproduce this issue with or without docker. Please create a sample Java application (source code without compilation errors) that will help us reproduce your problem on our end, and attach it here as a ZIP archive for testing. Also, please describe in more detail the testing methodology and attach the postman configuration file.

Hi, i moved the project to another pc and it successfully converted the two doc file to tiff.
Also, i added the “-Xms3G -Xmx4G” when running the jar and in both cases, that is, when running from intellij and when running using docker, the docs got converted successfully.

However, this means that aspose uses too much heap memory. Is this normal?
What is the “number of converters running at the same time” / “computer’s ram-cpu” relationship?

In other words, the question is if aspose is made that way so we could use it as an API converter. This means that many conversion processes could run at the same time.

@stsakas,

Performance and memory usage all depend on complexity and size of the documents you are generating. While rendering a document to fixed page formats, Aspose.Words needs to build two model in the memory – one for document and the other for rendered document.

The process of building layout model is not linear; for some documents, it may take a minute to render one page and may take a few seconds to render 100 pages, or vice versa. We are always working on improving performance; but, rendering will be always running slower than simple saving to flow formats (e.g. doc/docx).

In terms of memory, Aspose.Words does not have any limitations. If you are loading huge Word documents into Aspose.Words’ DOM, more memory would be required. This is because during processing, the document needs to be held wholly in memory. Usually, Aspose.Words needs 10 times more memory than the original document size to build a DOM in the memory.

We suggest you please use SaveOptions.MemoryOptimization property to optimize the memory performance. Setting this option to true can significantly decrease memory consumption while saving large documents at the cost of slower saving time.

As far as running multiple converters at the same time, Aspose.Words is thread-safe as long as only one thread is working on the document at a time. This is a typical scenario where one thread is working on one document. Different threads can safely work on different documents at the same time.

Hope this helps you. Please let us know if you have any further questions.

Please do the following:
If you are using Intellij, add the -Xmx2G vm options from “Edit configuration”.
Make sure is applied by printing: System.out.println(Runtime.getRuntime().maxMemory());

Use the following code:

        // tiff options
        ImageSaveOptions tiffOptions = new ImageSaveOptions(SaveFormat.TIFF);
        tiffOptions.setImageColorMode(ImageColorMode.GRAYSCALE);
        tiffOptions.setTiffCompression(TiffCompression.LZW);
        tiffOptions.setResolution(300);

        com.aspose.words.Document doc = new Document(inputFilePath);

        String convertedFilename = "foo" + ".tiff";
        String outputFilePath = outputFolderPath + File.separator + convertedFilename;

        doc.save(outputFilePath, tiffOptions);
        }

Please, try this for the two doc files i previously sent you. It should fail with a Java heap space error.
How can you explain this? Both files are very small in size.
Then try to run again the converter with -Xmx4G. It should work. What is also weird is that the output tiffs are 21.8mb and 25mb (for the specific tiff options) while the doc/docs are 250kb and 780kb.

@stsakas,

I tested this script with the specified vm config using IntelliJ with OpenJDK 11 and the latest version of Aspose.Words and didn’t find any errors on my side. Document conversion completed successfully, output file size is about 4 MB. Please attach an example Java project for which the error occurs on your side.

demo.zip (735.3 KB)

Here you go. The zip already contains the word files inside.

Case 1)
Notice that when you don’t include the license file, apart from the Aspose watermark, the output files (the tiff files), are indeed about 4MB BUT this is because the word file is not fully converted, just the first 5-8 pages of it! Is this the normal behavior?

Case 2) You apply the license: i) uncomment the commented code ii) place the license file inside the resources folder.
Run the program. The output tiff has now all the pages but its very large in size

Case 3) As i already told you, you set the vm option -Xmx2G and when you run the converter it throws the java heap error.

Please test this on your machine(s) and provide some feedback.
Thank you

@stsakas,

Thank you for providing the project. We will test it and let you know the results in this forum thread.

@stsakas,

We were able to reproduce this issue. It has been logged as WORDSJAVA-2721, we will keep you posted and will let you know as soon as the issue is resolved. Sorry for the inconvenience.

The issues you have found earlier (filed as WORDSJAVA-2721) have been fixed in this Aspose.Words for Java 23.12 update.