7

Similarly to this question, I received the following error:

[INFO] --- android-maven-plugin:3.3.0:dex (default-dex) @ betodef-android ---
[INFO] /usr/lib/jvm/java-6-sun-1.6.0.32/jre/bin/java [-Xmx1024M, {snip}
[INFO] 
[INFO] UNEXPECTED TOP-LEVEL ERROR:
[INFO] java.lang.OutOfMemoryError: GC overhead limit exceeded

This occurred after I added several dependencies, including fastutil, to my Android project. However, increasing the memory available for dex does not solve the problem.

Community
  • 1
  • 1
mikołak
  • 9,605
  • 1
  • 48
  • 70

1 Answers1

9

The problem lies in a limit of the dex format, specifically the 65536 limit on the number of method references.

To diagnose the problem, increase the memory to a much larger amount (enabling debugging/verbose output doesn't help, curiously enough). In my case, I added the following to the android-maven-plugin configuration:

<dex>
    <jvmArguments>
        <jvmArgument>-Xmx4096M</jvmArgument>
    </jvmArguments>
</dex>

After choosing a large-enough heap size, the message changes to include something like this:

[INFO] trouble writing output: Too many methods: 172296; max is 65536. By package:
[INFO]     20 android.app
[INFO]     18 android.content
[INFO]      1 android.content.pm
[INFO]      7 android.content.res
[INFO]      7 android.hardware
[INFO]     38 android.media
[INFO]     20 android.opengl
[INFO]     11 android.os
[INFO]      1 android.text.method
[INFO]      8 android.util
[INFO]     38 android.view
[INFO]      2 android.view.inputmethod
[INFO]     21 android.widget
...
[INFO]      3 com.google.common.annotations
[INFO]    746 com.google.common.base
[INFO]      9 com.google.common.base.internal
[INFO]    833 com.google.common.cache
[INFO]   8478 com.google.common.collect
[INFO]     50 com.google.common.eventbus
[INFO]    385 com.google.common.hash
[INFO]    597 com.google.common.io
[INFO]     92 com.google.common.math
[INFO]    134 com.google.common.net
[INFO]    521 com.google.common.primitives
[INFO]    404 com.google.common.reflect
[INFO]    954 com.google.common.util.concurrent
[INFO]     16 default
[INFO]    227 it.unimi.dsi.fastutil
[INFO]   1370 it.unimi.dsi.fastutil.booleans
[INFO]  17249 it.unimi.dsi.fastutil.bytes
[INFO]  17249 it.unimi.dsi.fastutil.chars
[INFO]  17279 it.unimi.dsi.fastutil.doubles
[INFO]  17263 it.unimi.dsi.fastutil.floats
[INFO]  17309 it.unimi.dsi.fastutil.ints
[INFO]    628 it.unimi.dsi.fastutil.io
[INFO]  17315 it.unimi.dsi.fastutil.longs
[INFO]  26514 it.unimi.dsi.fastutil.objects
[INFO]  17257 it.unimi.dsi.fastutil.shorts
[INFO]      2 java.awt
[INFO]      5 java.awt.datatransfer
[INFO]    206 java.io
[INFO]    346 java.lang
[INFO]     10 java.lang.ref
[INFO]     71 java.lang.reflect
[INFO]     27 java.math
[INFO]     26 java.net
[INFO]    108 java.nio
[INFO]      6 java.nio.channels
[INFO]      2 java.nio.charset
[INFO]     13 java.security
[INFO]      2 java.text
[INFO]    382 java.util
[INFO]    128 java.util.concurrent
[INFO]     33 java.util.concurrent.atomic
[INFO]     40 java.util.concurrent.locks
[INFO]      6 java.util.jar
[INFO]      6 java.util.logging
[INFO]     10 java.util.regex
[INFO]     20 java.util.zip
[INFO]     26 javax.microedition.khronos.egl
[INFO]    188 javax.microedition.khronos.opengles
[INFO]      7 sun.misc

As you can see, there is a huge amount of references in the fastutil classes.

There are two possible solutions of this problem:

  1. Use an alternative to the problematic dependency (duh).
  2. Use an optimizer such as Proguard (general Android, Maven-specific).
mikołak
  • 9,605
  • 1
  • 48
  • 70