Java garbage collection and atomic events/stop gc pauses interrupting a sequence of functional calls
Asked Answered
N

4

7

I have a complex large multithreaded application to which I am introducing new functionality.

I have added a call to a piece of specialist hardware (via a vendor supplied JNI lib). However before that (very fast) function is called some work is done beforehand to populate the data structure sent to it.

However the GC profile of the application is very choppy/bad and it seems that some of these population steps are being interrupted by GC. This matters because time needs to be kept constant or as constant as possible between the first of these events and the hand off to the hardware resource.

Is there a way to say, "sychronise for GC", these operations so that they won't be held up during stop the world GC pauses?

Using a 64bit 1.7 JDK on RHL5.5

Thanks

Novercal answered 26/3, 2013 at 11:24 Comment(6)
Just to clarify, are you seeing issues during full GC sweeps, or also doing minor GC sweeps?Danube
Short answer, no. If you are encountering stop the world gc that regularly there is something wrong. What gc settings are you using?Wad
JustSanyul, i believe it is during full the big problems happen (the sequence of operations can take many many milliseconds when it should take <5 microseconds. indeed to write operation on its own takes 1.3micros)Novercal
If you have realtime requirements, perhaps you should consider using a realtime platform.Brandish
Which type of GC are you using ? Have you tried G1[Garbage First] ?Sherwoodsherwynd
#4052466Epaulet
D
3

If it is in-fact during the full garbage collection you are experiencing the issues, then the question is what can you do to bring down the frequency of these full garbage collection sweeps.

First, try and analyse what circumstances triggers these full sweeps, are you running low on heap space in general? And if so, why are you frequently running low on heap (are there a potential leak somewhere?)

Also, during minor (the faster) garbage collections, objects are moved from the young generations (eden and survivor 1) to survivor 2. If it doesn't fit in survivor 2, they will be moved to tenured, if there isn't enough space in tenured, you trigger a full sweep. So, if your young generations are large, and you have a certain amount of long running objects, this might cause issues.

In the end of the day, you have to analyse it. Profile you application, and determine when and why you are seeing full garbage collections, and then tune your application to make them less frequent or potentially ensure that the are so infrequent you can "control" when they happen.

Danube answered 26/3, 2013 at 12:21 Comment(0)
K
2

GC behaviour is not deterministic, so you cannot ensure synchronization.

Three options come to my mind:

  • Are you creating a lot of objects to populate the data structure for each call? Maybe you can re-use them to avoid filling the heap and GC automatic calls.
  • Run the VM with more pre-assigned memory to space the gc calls.
  • Call System.gc() yourself when is not harmful for your application. This call is just a suggestion (JVM can ignore it), but I'll give it a try.

Anyway the best option for your needs is to use a true Real-Time language implementation instead Java

Kelvin answered 26/3, 2013 at 11:56 Comment(3)
Thanks Pablo.No the call itself reuses the same byte buffer for the duration of the application life cycle.Novercal
@pablo I think you mean "can't ensure...", not "can"?Senaidasenalda
I'm afraid my point was this is a large existing legacy application. It isn't practical to say throw it all away. My question was the GC issue for certain critical sectionsNovercal
M
2

Just for completeness, you could also use a JVM that implements Real-time Java (RTSJ).

In a real-time JVM, you can execute your time-sensitive task in a thread that will not be interrupted by any GC activities. Unfortunately, there is not many RT JVMs available out there these days.

Milliemillieme answered 26/3, 2013 at 21:18 Comment(0)
S
2

If you're building a new time sensitive task, and cannot fix the GC behavior of the JVM using the task, then one other option is that you could move the task to a separate JVM.

Interprocess/machine communication will mean there is a higher minimum performance, but in the separate JVM instance that does your JNI communication you could tune GC with more freedom than you have within the parent process and thereby get more control over the choppiness.

Senaidasenalda answered 27/3, 2013 at 2:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.