How to understand and debug InternalLimitsReached messages

As your MicroEJ application grows in size, a com.is2t.vm.support.InternalLimitsError error may be thrown by the MicroEJ Core Engine.

When it is followed with the message Too many alive java threads (<last thread id>), you may have tried to start too many threads at the same time. The first lead to follow is then to check at runtime the number of active threads using Thread.activeCount() [1].

If this gives you an abnormally high number of threads, then you just need to investigate further in that direction and add more threads (look at Target → Memory → Threads → Number of threads in your launcher configuration) or pinpoint the too many thread(s).

Otherwise, if the number of active threads is within the range you set in your launcher configuration, it is most likely an issue with too many monitors reached by the thread. You can increase their number in your launcher config (Core Engine → Memory → Maximum number of monitors per thread).

The exception should not appear anymore, but does this mean that the issue is solved for good? Not necessarily, as it depends on what was causing the InternalLimitsError in the first place.

There are two possible scenarios for reaching the limit of monitors:

  • The application just has a peek of resource needs. In this case, increasing the number of monitors indeed fixed the problem and all should be fine. However, please notice that the extra monitors will have an impact on the RAM footprint.
  • There is a leak in your application. In this case, more monitors will allow your application to work for a longer time, but it will ultimately run out of monitors again. You should then investigate on where monitors are leaking.

When you have found a high enough number of monitors, a good practice is to try to decrease it gradually to its original value until the error appears again. It will help you to determine the cause of the exception and it will ultimately make you save as much resources as possible.

Ultimately you may want to catch this InternalLimitsReached error to recover from the failure of your application, keep in mind most of the time the application will be in an unstable state, so use the possibility to catch the InternalLimitsReached error wisely. Nonetheless here is how to do it. Set the UncaughtExceptionHandler [2] for threads by using the Thread.setDefaultUncaughtExceptionHandler API.

[1] Thread
[2] Thread.UncaughtExceptionHandler