Tomcat – Memory problems with Tomcat on Solaris 10

64-bitsolarissparctomcat

I have a server running Solaris 10. It reports 70+ GiB free RAM. I am attempting to start Tomcat 7.0.68 using Java 1.7.0_80 in 64-bit mode.

The server is claiming that it is not able to allocate 717 MiB of RAM. I get an hs_err_pidxxx.log file each time I try it. It suggests this:

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 717225984 bytes for committing reserved memory.
# Possible reasons:
#   The system is out of physical RAM or swap space

No. There are 70 GiB available, it's trying to allocate 700ish MiB.

#   In 32 bit mode, the process size limit was hit

We're in 64-bit mode.

# Possible solutions:
#   Reduce memory load on the system

There is nothing else on this machine but the OS.

#   Increase physical memory or swap space

We already have two orders of magnitude more than needed.

#   Check if swap backing store is full

No.

#   Use 64 bit Java on a 64 bit OS

Done.

#   Decrease Java heap size (-Xmx/-Xms)

Would if I could.

#   Decrease number of Java threads

How is this done?

#   Decrease Java thread stack sizes (-Xss)

Suggested values? It's at default, but I don't know what that is to tweak it.

#   Set larger code cache with -XX:ReservedCodeCacheSize=

Again, we're at default.


$ swap -s
total: 48607296k bytes allocated + 18201336k reserved = 66808632k used, 311770552k available

Best Answer

Free RAM simply means there is nothing stored in it. That doesn't mean you can use it. It is perfectly possible for the RAM reported to be free not to be usable by your new JVM because other applications have reserved it. In any case, the JVM, just like most applications doesn't ask for RAM but for virtual memory. This is more than likely the issue your system is suffering, a lack of virtual memory.

You'll know your virtual memory usage with that command:

swap -s

The simple answer to a virtual memory shortage is simply to increase (or create) a swap area for the memory reservations to have a backing store area.

Edit: With the additional information you posted, the reason why your application cannot allocate more virtual memory is due to the fact your are running in a non global zone where memory capping is in place. Non global zones are containers, i.e. they all share the same kernel. However, their resource usage can be limited to prevent one zone to disturb the other ones.

Outside stopping other processes that use virtual memory, there is nothing you can do from this zone, even as root. You need to ask the global zone administrator to grant more virtual memory to your zone, in your case the zone.max-swap setting.