App with hundreds of code splits won't finish compiling

93 views
Skip to first unread message

hindog

unread,
Sep 27, 2011, 5:06:35 AM9/27/11
to Google Web Toolkit
I have an app that generates hundreds of additional classes during
compile that I then manage via a single class that uses GWT.runAsync
to perform code splitting so that I can load these classes lazily at
runtime.

My problem is that the compile never finishes, it will just eat up all
of my system ram until either my system becomes unresponsive, or the
compiler chokes out with an OutOfMemoryException. I've tried
compiling with up to 50GB available to the compiler and no avail (it
will use it all). I am using GWT maven plugin with localWorkers=1 to
keep the permutation compilation to 1 worker thread. I want the
compileReport, so I have that turned on, but it doesn't help if it's
turned off, either.

Without code splitting, the compile finishes, but my app weighs in
pretty heavy, so that's why I'm looking to get the code split working.

My questions are:

Has anyone else tried to do a massive amount of code splitting
(hundreds or more) and had success?

Does anyone have any internal knowledge on how code splits are handled
by the compiler that might cause this? I've hooked up a profiler and
can see that the majority of the heap is getting used by HashMap and
char[].

As a test, I short-circuited the generation stage to generate only 6
classes total, instead of the 100's that would normally be generated,
and the compile finishes no problem (and the code splits look OK).
For that run, here is a snippet from my compilerMetrics.xml:

<compilation id="0" elapsed="11490" totalElapsed="102756"
description="ClientBundle.enableInlining=true,compiler.emulatedStack=true,compiler.predeclare.cross.fragment.references=false,compiler.stackMode=emulated,gwt.forceBidi=false,gwt.logging.enabled=FALSE,gwt.rpc.hijackLegacyInterface=false,gwt.suppressNonStaticFinalFieldWarnings=false,locale=default,log_ConsoleLogger=ENABLED,log_DivLogger=DISABLED,log_FirebugLogger=DISABLED,log_GWTLogger=ENABLED,log_RemoteLogger=NOT_SET_BY_APPLICATION,log_SystemLogger=ENABLED,log_WindowLogger=DISABLED,log_level=DEBUG,user.agent=gecko1_8,videoElementSupport=maybe,audioElementSupport=maybe,canvasElementSupport=maybe,storageSupport=maybe,touchEventSupport=maybe">
<javascript size="1207093" fragments="8">
<fragment initial="true" size="327554" />
<fragment size="134847" />
<fragment size="34126" />
<fragment size="96050" />
<fragment size="139174" />
<fragment size="31457" />
<fragment size="329674" />
<fragment size="114211" />
</javascript>
</compilation>

I think my next step is to hook a debugger up to the compiler, but I
figured I shoot this out there just in case.

Cheers,

Aaron

Eric Andresen

unread,
Dec 21, 2011, 5:10:05 PM12/21/11
to google-we...@googlegroups.com
Hi Aaron,

  Did you ever find a way to make this work?  I'm running in to the same problem.  I have an app that currently compiles to about 12mb of javascript, but that single large file is killing my load times on IE.  
  I tried splitting it at my most logical spots, which causes about 100 split points.  When I have just a few splits, it works fine. But when I try to do the full splitting, the compile takes an order of magnitude longer and usually blows the heap space before it finishes.  

  This is on some relatively small hardware, but I'm giving the compiler 3gb of memory to work with and limiting it to a single localWorker thread.  Without the split points, I can compile it with just over 1gb of memory.

Thanks,
Eric

Ed

unread,
Dec 22, 2011, 3:25:42 AM12/22/11
to google-we...@googlegroups.com
I would split your app in several gwt modules if possible.
Currently code splitting isn't optimal for such sizes.
See Issue: 6612
This is being worked on as we speak.

Raphael André Bauer

unread,
Dec 22, 2011, 4:32:55 AM12/22/11
to google-we...@googlegroups.com

Two things: 12 MB sounds really really really large. We got some
really large apps up and running and they always were below 2MB. Not
sure - maybe there is potential for optimization.

The other thing is: "Hundreds of code splits" sound really large. How
big are your split points? I assume they are rather small. And if they
are too small the whole notion of code splitting does not make sense.

Maybe you could study the soyc and split your app into several modules
with acceptable sizes to balance download size and number of split
points...


Best,

Raphael

>
> --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-web-toolkit/-/dMfpYC_xRvEJ.
>
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-web-tool...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.

--
inc: http://ars-machina.raphaelbauer.com
tech: http://ars-codia.raphaelbauer.com
web: http://raphaelbauer.com

Alan Leung

unread,
Dec 22, 2011, 4:44:17 AM12/22/11
to google-we...@googlegroups.com
FYI: I am working on re-writting the code splitting algorithm:

http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter2.java

Soon I'll be checking in an experimental -X flag that let people use the new algorithm.

I can see why there isn't going to be enough memory to do code splitting with 100+ split points. The currently code splitter needs to run 100 control flow analysis on the whole program while keeping the result in memory.

The new algorithm should be able to avoid that but I am not 100% certain it can handle your application without doing some tests / experimentation.

-Alan

Ed Bras

unread,
Dec 22, 2011, 5:33:30 AM12/22/11
to google-we...@googlegroups.com
@Alan: good news
I am starting to think that I am making baby app's with only around 5-10 split points and < 1.5MB (unzipped) initial load ;)

Eric Andresen

unread,
Dec 22, 2011, 10:04:03 AM12/22/11
to google-we...@googlegroups.com
Granted, it is a pretty big project, it has about 800 activities, 150 EntityProxy types, 100 Request objects, and uses all the goodness of the RequestFactory and UiBinder for all of it.  (There is a ton of inheritance so most of those activities are only 50-100 lines of code.  Only the object-specific code in each remains, at least until http://code.google.com/p/google-web-toolkit/issues/detail?id=6794 is fixed)

The current split points are on each top-level domain object, each of which contain about 5-10 activities.  Each generates about 50-150kb of JS when they work.  The idea was that the user would have a small initial download, and then a slight delay each time they hit a new object type they hadn't used before.

I guess I could move the splits to the package level in the object hierarchy and only have about 8 split points, each with about 100 activities.  That should leave the initial download the same, but have a bigger run-time hit when the user crosses that boundary.  


Ed Bras

unread,
Dec 22, 2011, 10:45:35 AM12/22/11
to google-we...@googlegroups.com
I guess I could move the splits to the package level
As you might have notices you have to choose your split points with care as otherwise you shoot yourself in the foot.
Having more split points doesn't necessary means a "better" app.
A few rules of thumbs for adding split points:
- A split point contains a considerable amount of the total app size. For example: 10%.
- The split point contains code that corresponds to an "isolated" functionality chunk. 

Uses the generated soyc report for split point optimization.


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

Alan Leung

unread,
Dec 22, 2011, 6:17:10 PM12/22/11
to google-we...@googlegroups.com

I guess I could move the splits to the package level
As you might have notices you have to choose your split points with care as otherwise you shoot yourself in the foot.
Having more split points doesn't necessary means a "better" app.

Adding crazy amount of split points will make your initial download smaller. But because of how the code splitter works, you'll end up with bigger and bigger leftover fragments. At least until I check in and enable the new code splitting algorithm.

 
A few rules of thumbs for adding split points:
- A split point contains a considerable amount of the total app size. For example: 10%.

While I've seen well structured apps with 50 split points or so, like Ed Bras suggested, they took lots of caution in where they are inserting them, checking the SOYC every once a while.

-Alan

Deepak Singh

unread,
Dec 23, 2011, 9:09:53 AM12/23/11
to google-we...@googlegroups.com
So how long will it take for the new code splitting algorithm to be checked in ?
--
Deepak Singh
Reply all
Reply to author
Forward
0 new messages