0

does anyone know was the proper configuration/development approach when writing an application that only uses cache as store?

To give some background, the application doesn't need to store any information (it actually stores a timestamp but I'll explain that later) because it only reads from what another app writes. We have a stored procedure that reads from that application's database and returns us the information at that point. From the moment the application starts, any update is notified through a topic so that database is no longer needed (until next restart).

Once everything is loaded, every record in the cache has to be read when certain messages are consumed to loop through them an process them individually. The application keeps a Map of Lock objects, each one for each record in the cache, to avoid race conditions. If the record meets certain criteria, a timestamp is written to the cache and to a database using write-behind of up to 5000 records.

The application is already developed but I think we have some problems with GCs. We keep getting spikes and I would like to know if there is any recommendation on what to do to reduce them.

These are the things we've done so far:

  • There is a collection of Strings that are repeated over and over for each record. I'm interning these ones (we are using java 8)
  • The cache we are using is EhCache. To avoid recreating objects, the element from the cache is used directly.
  • Every variable is a long or a String, except for an enum value and a LocalDateTime that is required to do some date checks.
  • There are two caches. This is because, once a criteria is met, a timestamp has to be replicated to another instance of the app. For this, we are using JMS replication from EhCache that uses topics for these updates.
  • The timestamp updates don't happen very often so the impact this could have should be minimum.
  • The amount of records is, at the moment, 350000, each one with a bunch of Strings and longs alongside the enum and LocalDateTime mentioned before.
  • A random problem we have is that sometimes it throws GC overhead limit exceeded. Normally the application keeps lowering the amount of memory it uses after some GCs but it seems sometimes it cannot handle the load.
  • The box has 3GB of memory for this and the application after a major GC uses around 500MB for the cache.

Apart from this, I don't know how the JVM is configured or what kind of GC uses. Any ideas or any blogs or documents someone could suggest me to start reading?

Thanks!

Juan Vega
  • 1,030
  • 1
  • 16
  • 32
  • Telling this out of the blue is difficult without knowing which jre and setup you use – Marged Nov 05 '15 at 19:18
  • But first you should _prove_ your theory because I consider it unlikely that you really have a GC problem with that little memory used – Marged Nov 05 '15 at 19:24
  • The jre is java 8 and I think is the one from Oracle but this last part i don't know exactly as I don't have access to the box.I can ask about the configuration but I'm not an expert on it so I don't know what needs to be asked.that' why I was asking if, given the nature of the app, there are some configurations that should be applied to tweak it or if the application should be developed in a memory friendly way – Juan Vega Nov 05 '15 at 19:26
  • We have AppDynamics but even trying it locally and using VisualVm you can see the spikes and how it goes down in memory used after a major GC – Juan Vega Nov 05 '15 at 19:27
  • Sorry, this is a bit like going to the doctor and say: "Ouch! But you mustn't touch me. Just prescribe me what helped others the most". But you can always try to find best practices for ehcache and selecting the garbage collector. But - hey - you don't know which you already use, I forgot ;-) – Marged Nov 05 '15 at 20:25
  • *"A random problem we have is that sometimes it throws `GC overhead limit` exceeded."* there are plenty of questions covering that on SO. Start with those. – the8472 Nov 05 '15 at 20:47
  • Possible duplicate of [how to solve 'java.lang.OutOfMemoryError: GC overhead limit exceeded'](http://stackoverflow.com/questions/12813203/how-to-solve-java-lang-outofmemoryerror-gc-overhead-limit-exceeded) – the8472 Nov 05 '15 at 20:50
  • My intention was just to ask if anyone knew of options that could be used for the JVM when RAM was used as the main store for the app. Some hints of what to start checking and what to look for in the code as is the first time I work in an app like this.The configuration in the box is this `-XX:+UseParallelGC -XX:+UseParallelOldGC -Dsun.rmi.dgc.server.gcInterval=0x7ffffffffffffffe -Dsun.rmi.dgc.client.gcInterval=0x7ffffffffffffffe -XX:+DisableExplicitGC -Xms2048m -Xmx2048m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:logs/verboseSunGC.log -XX:+HeapDumpOnOutOfMemoryError` – Juan Vega Nov 06 '15 at 16:06
  • Sorry if it wasn't enough info. I tried to write everything I came to my mind that could be helpful about the app but I guess I left things out (like JVM config). The GC overhead limit I guessed it was related to the amount of garbage generated but I thought the problem could also be related to options in the JVM – Juan Vega Nov 06 '15 at 16:09

1 Answers1

1

As you are running Java 8 you could change the Garbage Collector. The so called "Garbage First" GC has been there as an option since early versions of Java 7. Problems from its infancy have been resolved and it is often recommended for interactive applications that need fast response.

It can be enabled by using -XX:+UseG1GC and will become the default on Java 9.

Read more about it at http://www.oracle.com/technetwork/tutorials/tutorials-1876574.html

Marged
  • 10,577
  • 10
  • 57
  • 99
  • I've just been suggested the same thing by a colleague to improve the performance.we'll try that next week and see how it goes.thanks! – Juan Vega Nov 06 '15 at 18:35