Java Heap Configuration for Redundant Ignition Gateways

Good morning,

I’m working on a project that involves two redundant Ignition gateways. Both servers have 64 GB of RAM, and neither hosts a local database, the database resides on a separate machine within the network.

The project includes approximately 40.000 tags and uses Sepasoft MES modules, which adds significant processing requirements.

I would appreciate your advice on configuring the Java heap. Currently, the settings in ignition.conf are as follows:

Initial Java Heap Size (in MB)

wrapper.java.initmemory=8192

Maximum Java Heap Size (in MB)

wrapper.java.maxmemory=31744

I’ve read that allocating more than 32 GB can disable pointer compression (Compressed OOPs), which may lead to higher memory consumption and reduced performance.

Could you confirm if this configuration is optimal, or suggest best practices for this scenario?

Thank you for your guidance.

  1. Always set initial heap equal to max heap. Let java grab it all up front.

  2. Monitor your actual runtime memory usage. It should make a sawtooth on the gateway's time series chart. I recommend tweaking to achieve a sawtooth that swings from ~40% usage to ~85% usage.

  3. Ensure there is a setting for the GC stall target. I recommend 250ms or less.

Hi Phil,

Since the redundant servers have 64 GB of RAM, would it be possible to allocate more than 32 GB to the initmemory and maxmemory parameters without any issues?

Thanks so much for your help!

Best regards,
Antonio

I do not know anything about the pointer compression issue, sorry. I would think if you need the heap, having it will outweigh other considerations.

I do know that giving Ignition a lot more memory than it normally needs can create occasional stalls when the heap finally creeps up towards the max. It can also trick hypervisors into swapping out what appears to be inactive memory, with huge latency spikes when java gets to it.

You should aim for the bottom of the sawtooth to be ~ 40% of your heap.

Thanks so much Phil, I will apply your knowledge.

Best regards,
Antonio

Are you talking about this one? It’s the only thing I could find that sounds similar.

wrapper.jave.additional.14=-XX:MaxGCPauseMillis=100

P.S. Just noticed it’s jave. I hope it works.:nerd_face:

1 Like

It needs to be spelled correctly. But yes that is the config @pturmel is talking about.

1 Like

Yes. 250ms is good enough for most users. People doing high speed data collection, like users of Class1 EtherNet/IP, usually need 100ms or even 50ms there.

1 Like

I’ve copy-pasted it from the conf file like that :man_shrugging:

Don't know what to tell you. It needs to be wrapper.java.additional.14=-XX:MaxGCPauseMillis=100not wrapper.jave.additional.14=-XX:MaxGCPauseMillis=100. So it is ignoring that config and will continue to ignore it until you fix it.

2 Likes

The default max pause time is 200ms, so you're actually relaxing it a bit by setting it to 250ms.

Most people don't need to change this.

1 Like

Hmmm. I obviously haven't kept up with java changes. :frowning:

It doesn't seem to be documented. I didn't find a source I trusted until I went to the actual source: jdk17/src/hotspot/share/gc/g1/g1Arguments.cpp at 4afbcaf55383ec2f5da53282a1547bac3d099e9d · openjdk/jdk17 · GitHub

I thought it was 1000ms in java 11, which didn't play well with Ignition's drift detector.