[ERROR] OutOfMemoryError: Increase heap size or lower gwt.jjs.maxThreads

174 views
Skip to first unread message

viny...@gmail.com

unread,
Sep 24, 2024, 11:58:36 AM9/24/24
to GWT Users
Hi everyone,

We have stucked in a very strange / awkward situation. Our running GWT 2.6.1 application started crashing at the time of compilation since 2 days back.

We are using netbeans IDE (non-maven). we are sharing our app-information as follows:
1. "WAR" SIZE : 591MB

2. Total "*.gwt.rpc" files : 891 files (we have attached some of the *.gwt.rpc files for ref.)
                    Screenshot 2024-09-24 205607.png

3. "*.cache.html" SIZE : 4.15 MB 

4. Earlier when WAR was compiling it was taking max 50 minutes for full comilation (single permutation) on hardware of (64 GB RAM, 4 Core, Xeon (R) CPU E3-1225 v5 @3.30 GHz,  window-server 2019 standard)  

5. using JVM option -Xmx61440M (gwt-conpilation config attached for ref.)

6. Currently we are getting following error: 
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
   Compiling 1 permutation
      Compiling permutation 0...
      [ERROR] OutOfMemoryError: Increase heap size or lower gwt.jjs.maxThreads
java.lang.OutOfMemoryError: Java heap space
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:133)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:220)
at java.io.Writer.write(Writer.java:157)
at com.google.gwt.core.ext.soyc.impl.DependencyRecorder.flushOutput(DependencyRecorder.java:136)
at com.google.gwt.core.ext.soyc.impl.DependencyRecorder.endDependencyGraph(DependencyRecorder.java:70)
at com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitter.computeComplementCfaForFragments(CodeSplitter.java:325)
at com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitter.computeExclusivityMapWithFixups(CodeSplitter.java:362)
at com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitter.execImpl(CodeSplitter.java:480)
at com.google.gwt.dev.jjs.impl.codesplitter.CodeSplitter.exec(CodeSplitter.java:115)
at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.compilePermutation(JavaToJavaScriptCompiler.java:423)
at com.google.gwt.dev.jjs.UnifiedAst.compilePermutation(UnifiedAst.java:137)
at com.google.gwt.dev.CompilePerms.compile(CompilePerms.java:195)
at com.google.gwt.dev.ThreadedPermutationWorkerFactory$ThreadedPermutationWorker.compile(ThreadedPermutationWorkerFactory.java:50)
at com.google.gwt.dev.PermutationWorkerFactory$Manager$WorkerThread.run(PermutationWorkerFactory.java:73)
at java.lang.Thread.run(Thread.java:750)
         [ERROR] Out of memory; to increase the amount of memory, use the -Xmx flag at startup (java -Xmx128M ...)
      [ERROR] Unrecoverable exception, shutting down
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
at com.google.gwt.dev.ThreadedPermutationWorkerFactory$ThreadedPermutationWorker.compile(ThreadedPermutationWorkerFactory.java:56)
at com.google.gwt.dev.PermutationWorkerFactory$Manager$WorkerThread.run(PermutationWorkerFactory.java:73)
at java.lang.Thread.run(Thread.java:750)
      [ERROR] Not all permutation were compiled , completed (0/1)
F:\users\Avinash\forNewPlugin\aarogya\nbproject\build-gwt.xml:333: The following error occurred while executing this line:
F:\users\Avinash\forNewPlugin\aarogya\nbproject\build-gwt.xml:482: Java returned: 1
BUILD FAILED (total time: 39 minutes 36 seconds) 


We request you all to please provide any help / guidance on the same. 








3EEC422421A0604EE74C95B5A8919AA9.gwt.rpc
29BD07BE9922FF92538F9C1DE6EBC64F.gwt.rpc
3B8E2AFC87172A263453F68796E5A353.gwt.rpc
gwt-compile-config.png
5A27C3D925817420B088E5845D2BA80D.gwt.rpc
62C5453DE03F2B964E26342D6250D960.gwt.rpc

Jens

unread,
Sep 25, 2024, 5:40:36 AM9/25/24
to GWT Users
Are you using a lot of code split points? 61GB memory seems pretty high. Someone else once posted a similar question and this person had ~100 split points which significantly impacted compilation. The more split points you have the more complex analysis will be in order to determine if some code is unique to a split point.

As comparision I have an app that produces 10MB JS in total per permutation and compiles fine using 4GB memory. It uses about 12 split points.

Colin Alworth

unread,
Sep 25, 2024, 9:44:35 AM9/25/24
to GWT Users
Agreed with Jens, definitely look at your split point usage. In the war that you have, you have a .cache.html file that you mentioned, 4.7MB. In that same dir, there should be a deferredjs/ directory - can you list its contents? It should have a directory per permutation (so, just one, named the same as your .cache.html file), and inside that, there should be some number of .cache.js files. How many are there, and what is their size range (like the .gwt.rpc table you made)?

Odds are very high that a significant number of them are quite small, and so shouldn't be created at all, so you can either remove them from your code (by finding their GWT.runAsync(...) calls), or use the compiler's built-in feature to try to minimize them, `-XfragmentCount=N`. That N is treated as a suggestion, and the compiler will create approximately that many split points in the final output - if that number is substantially less than the number of GWT.runAsync() calls, you probably will see a substantial compile time and memory usage improvement.

If most/all of the split points are small (say, under 100KB), you might consider disabling split points entirely to skip this processing step. There will be an increase in your initial page size, but possibly a manageable one.

But the most important thing when using split points is to measure impact on the user - when you load the page, watch the Network tab in browser tools, and see how much you are actually deferring, how many split points are being loaded, and how big they are. Odds are pretty high that the very last (going by file name) split point is loaded very soon after page load, and that this file is one of the biggest if not the biggest, which itself suggests that some work is necessary to improve your page loading experience. That split point is the "leftover" chunk, and represents any code shared by two or more chunks - using the -XfragmentCount feature is very likely to reduce its size, but modeling how your page loads and application builds is more complex than can be written in an email.

One more simple point: consider turning off the compiler report flag if you aren't actively using the results, it will take extra memory, compile time, and disk space. It would be helpful to turn it back on periodically, but shouldn't be necessary to keep it on all the time for all developers. This tool assists in some of the "why are my split points the way they are" debugging, but if the compile doesn't succeed anyway, odds are no one is looking at it.

Finally, GWT 2.6.1 is more than a decade old - if you're actively developing this application, strongly consider updating.

viny...@gmail.com

unread,
Sep 26, 2024, 7:24:44 AM9/26/24
to GWT Users

Thank You 
JENS & COLIN for providing your inputs and valueable suggestions. We have applied the same in our application and here is the result:

currently our defferedJs are as follows:
                   Screenshot 2024-09-26 140941.png
 
but after we removed all split points and only kept some major ones, here is the result:
                   Screenshot 2024-09-26 141151.png 

Now! our WAR is compiling (single permutation) in 10.25 mins only. We are testing our application workflow as many of the differedJS files are greater than 1 mb. We'll try to reduce the size. 

We again want to express our gratitude to JENS & COLIN for showing the right path towards the root cause along with the solution.  




Whereas GWT 2.6.1 upgradation is concerned, we would like to say, yes! we are actively developing the application and are intrested in upgrading GWT 2.6.1. But there are some issues which are required to be addressed. Many time earlier we have planned the upgradation, but dropped the idea due to not having the clear answers on bellow mentioned points. 

1. Which version of GWT we should move to? As many of the latest technologies are rolling arround and GWT in itself also have released many versions after 2.6.1. Meanwhile J2CL had also been launched. Migrating a huge application rapidly is not possible, so we want to be very sure.   

2. We are using "Apache Netbeans IDE" from a long time and now the team is also very much famlier with it. Upgraded GWT4NB plugin was missing from market place. Can we go for upgradation without changing IDE?

3. We are using "JDK 1.8". Do we required to upgrade JDK too?

4. We are using "PAYARA-WEB-SERVER" in both development + Production environment. GWT upgraded versions are comming with inbuild JETTY servers. Can we use "PAYARA-WEB-SERVER" in development after upgradtion or we have to stick wit JETTY only?

5. We are using "ANT build" not "Maven build" means we are not having any type of POM files.  

6. We are using sencha (gxt 3.1.1) mainly for GRID functionality. Upgrading GWT will fall dependency is on SENCHA-GXT and upgraded SENCHA-GXT is paid. What are its alternative?

7. Our application is having GWT standard architecure eg: (client + shared + server) in the same application. We want to split our application as client & server seperate. Where we want to move server part in SPRING-BOOT without any major changes. Is it possible?    

For detail discussions we can connect on viny...@gmail.com. We welcome any type of suggestions or involvement on the same. 

Jens

unread,
Sep 26, 2024, 12:49:22 PM9/26/24
to GWT Users
Now! our WAR is compiling (single permutation) in 10.25 mins only. We are testing our application workflow as many of the differedJS files are greater than 1 mb. We'll try to reduce the size. 

Sounds way better and you can likely decrease the required Java heap now as well. You had A LOT of split points. Personally I use split points more like one per menu item of the first or second level menu, depending on the size of the application. Grouping menu items behind a single split point can also make sense, e.g. user vs. admin menu items or based on other usage patterns. Occasionally I use split points for a feature like rendering charts that could be split away until needed. 



Whereas GWT 2.6.1 upgradation is concerned, we would like to say, yes! we are actively developing the application and are intrested in upgrading GWT 2.6.1. But there are some issues which are required to be addressed. Many time earlier we have planned the upgradation, but dropped the idea due to not having the clear answers on bellow mentioned points. 

1. Which version of GWT we should move to? As many of the latest technologies are rolling arround and GWT in itself also have released many versions after 2.6.1. Meanwhile J2CL had also been launched. Migrating a huge application rapidly is not possible, so we want to be very sure.   

The newest GWT 2.11 version will be fine. It still supports running on Java 8 but future versions will likely not.

 
2. We are using "Apache Netbeans IDE" from a long time and now the team is also very much famlier with it. Upgraded GWT4NB plugin was missing from market place. Can we go for upgradation without changing IDE?

I don't know about Netbeans and GWT4NB. However GWT SDK itself hasn't changed in structure so I don't see why GWT4NB shouldn't work anymore with newer GWT versions. Of course you can use GWT without any IDE plugin and launch GWT SuperDevMode and GWT Compile via ANT for example. Of course you would loose all benefits the IDE plugin gave you.
 

3. We are using "JDK 1.8". Do we required to upgrade JDK too?

No, as of now. But future versions will require newer JDK. If you upgrade your libraries then you can probably pretty easily upgrade JDK as well. You might need to add some libraries as some classes have been removed from JDK 11, see: https://www.oracle.com/java/technologies/javase/11-relnote-issues.html#JDK-8190378
 

4. We are using "PAYARA-WEB-SERVER" in both development + Production environment. GWT upgraded versions are comming with inbuild JETTY servers. Can we use "PAYARA-WEB-SERVER" in development after upgradtion or we have to stick wit JETTY only?

GWT ships with Jetty for convenience to get a demo app up and running quickly. But these days we recommend using your own servlet container and it can be any servlet container you like. If you do not use any servlet specific features of GWT like GWT-RPC or RequestFactory then you can use whatever server you like. PAYARA should continue to work fine.

 
5. We are using "ANT build" not "Maven build" means we are not having any type of POM files.  

Then you likely have a project or a folder with all your dependencies. You can download GWT from gwtproject.org, unzip it and use these jars in your ANT file. Alternatively there are ANT tasks provided by Maven which allows ANT to download dependencies based on POM files. See: https://maven.apache.org/resolver-ant-tasks/

 
6. We are using sencha (gxt 3.1.1) mainly for GRID functionality. Upgrading GWT will fall dependency is on SENCHA-GXT and upgraded SENCHA-GXT is paid. What are its alternative?

That is probably the main issue to solve. There are some UI widget libraries for GWT like https://dominokit.com/solutions/domino-ui/v2 but if you switch the library you would need to rewrite your code of course. 

Maybe you can make GXT work by patching it yourself if allowed.

 
7. Our application is having GWT standard architecure eg: (client + shared + server) in the same application. We want to split our application as client & server seperate. Where we want to move server part in SPRING-BOOT without any major changes. Is it possible?    

Sure. First split your application without using spring boot and make it run again. Then apply spring boot to your server project. GWT 2.11 also has a JakartaEE variant now so Spring Boot 3+ should work as well (but requires Java 17). The benefit of splitting your project into three is that you can also use different JDK versions for client and server projects. Sometimes that is useful if your server has JDK requirements that are either newer or older than what you want to use for the client.


Frank Hossfeld

unread,
Sep 27, 2024, 4:25:26 AM9/27/24
to GWT Users
Regarding point 7:
In addition to what Jens said, here you'll find an artifact creator for a Spring Boot + GWT archetype: https://github.com/NaluKit/gwt-maven-springboot-archetype

Also, I would like to add:
to prepare the project, running 'mvn clean compile'  is all you need to do to prepare the project for testing.
After the 'mvn clean compile' command is executed, start the codeserver and wait until you see the URL of the codeserver in the terminal window! After the URL is printed, the Spring Boot application can be started. This is necessary, because the codeserver has to create the launcherDir before Spring Boot is startet. Otherwise Spring Boot will not publish the content of the launcherDir and the project will not work.

viny...@gmail.com

unread,
Sep 30, 2024, 3:41:45 AM9/30/24
to GWT Users
Thank you  
JENS & FRANK for your valuable input. Your suggestions will surly help us in upgrading the version. 

viny...@gmail.com

unread,
Sep 30, 2024, 9:09:30 AM9/30/24
to GWT Users
Hi FRANK,

We have gone through the link provided by you "Spring Boot + GWT archetype: https://github.com/NaluKit/gwt-maven-springboot-archetype"

We want to host client on different server-machine and server will be hosted on another server-machine. We cannot find how will we achive the same with the architecture provided above. 



On Friday, September 27, 2024 at 1:55:26 PM UTC+5:30 Frank Hossfeld wrote:

Craig Mitchell

unread,
Sep 30, 2024, 8:51:40 PM9/30/24
to GWT Users
Running multiple servers with different functionality, is outside the scope of the Spring Boot + GWT archetype.

Spring Boot + GWT archetype gives you one server codeline, Ie: One WAR or JAR.  You can can replicate and load balance it nicely (I do this with this architecture in the Google Cloud).  I suspect this is actually what you want.

However, If you really want to run multiple servers that have different functionality (Ie: Create multiple different WARs or JARs), you'll need to create your own services.  How you do this is up to you, but the Spring Boot + GWT archetype will be able to call these services no problem.

Frank Hossfeld

unread,
Oct 1, 2024, 12:48:50 AM10/1/24
to GWT Users
Besides that the plugin does not provide this functionality - as Greg already mentioned - you will run into security issues, while hosting the client on one server and the server part on another (CORS). (OK, you might find a workaround with some fanzy server configuration, but it's risky) If you really want to do this, you can use the artifact as designed and use the server module of your client service as proxy that calls the other server. In this case you can use the artifact as designed and there is no need for disabling CORS and so.

Leon Pennings

unread,
Oct 2, 2024, 1:53:28 AM10/2/24
to GWT Users
I've seen the request to host static webcontent (i.e. html/css/js) on a separate server many times before. Especially with dedicated infrastructure teams.
The trick is to have mvn build a separate jar with only the static content and unzip that on the target webserver.
It's been a while since I last did this though.

Still I'm quite interested why we've never run in similar compilation issues despite having quite a larger set of frontend code as stated in this thread. Can someone explain? I expect it might have something to do with the fact we only use a single RPC call? 
The RPC is used as transport only for a command pattern implementation of the communication between front and backend. The Rpc basically implements a CommandSink in the UI code and a CommandSource on the server. 
Hence we always only needed a single rpc.

Op dinsdag 1 oktober 2024 om 06:48:50 UTC+2 schreef Frank Hossfeld:

Craig Mitchell

unread,
Oct 2, 2024, 3:04:22 AM10/2/24
to GWT Users
Oh, they are asking how to use a CDN (Content Delivery Network).  Please ignore my previous reply.

That's easy, when doing a "mvn clean package" to build the war (or jar), all the static files will in the server module in target/[proj-name].  Just copy them to your CDN.

Jens

unread,
Oct 2, 2024, 4:49:40 AM10/2/24
to GWT Users
Still I'm quite interested why we've never run in similar compilation issues despite having quite a larger set of frontend code as stated in this thread. Can someone explain? 

Because you have way less code split points. A lot of code split points will significantly increase compilation time and memory usage. If I do not misunderstand the table posted by the person who started the discussion, the code in question had nearly 800 split points. Maybe the algorithm in GWT compiler can be optimized but currently if you have that many split points GWT compilation will be resource hungry. 

-- J.

Reply all
Reply to author
Forward
0 new messages