<p>We are running a Java application in a Kubernetes cluster. The application itself doesn't have high demand for RAM, but I've noticed that it always consumes 1GB.</p>
<pre><code>kubectl top pods
NAME                                                              CPU(cores)   MEMORY(bytes)
my-application-c0ffee                                             100m           1127Mi
my-application-c0ffee                                             100m           1109Mi
</code></pre>
<p>When I checked <code>jcmd &lt;pid&gt; GC.heap_info</code> inside the container, I got the following:</p>
<pre><code>def new generation   total 89216K, used 12090K [0x00000000bc200000, 0x00000000c22c0000, 0x00000000d2c00000)
  ...
tenured generation   total 197620K, used 151615K [0x00000000d2c00000, 0x00000000decfd000, 0x0000000100000000)
  ...
Metaspace       used 146466K, capacity 152184K, committed 152576K, reserved 1183744K
  class space    used 18171K, capacity 19099K, committed 19200K, reserved 1048576K
</code></pre>
<p>As I understood, by default Java reserves 1GB of <em>virtual</em> memory size for storing Class information (in order to reference it in a compressed manner using 32 bit references this memory block should be reserved beforehand). When running outside of a container that's not a big deal, because this memory is not actually <em>committed</em>. It's only an address space that is <em>reserved</em>.</p>
<p>But it seems to be completely different situation in case of running inside container, where <em>reserved</em> memory becomes <em>committed</em>.</p>
<p>Does this mean that Java running in a container will by default consume at least 1GB of RAM?
And is there any other way to deal with that besides explicitly setting <code>-XX:CompressedClassSpaceSize</code>?</p>

<blockquote>
<p>in case of running inside container, where reserved memory becomes committed</p>
</blockquote>
<p>No, reserved memory does not &quot;become committed&quot;. The Virtual Size and the Resident Set Size are different metrics, whether in a container or not. What sits in the physical memory is RSS.</p>
<p><code>kubectl top</code> does not show you the RSS, but rather so-called &quot;working set&quot;, which does not always match the real memory usage.</p>
<blockquote>
<p>Does this mean that Java running in a container will by default consume at least 1GB of RAM?</p>
</blockquote>
<p>No.</p>
<blockquote>
<p>is there any other way to deal with that</p>
</blockquote>
<p>It depends on your goals. If you'd like to see the actual container memory statistics, look at <code>/sys/fs/cgroup/memory/.../memory.stats</code> and <code>memory.usage_in_bytes</code>. Or if you use docker, run <code>docker stats</code>.</p>
<p>If you'd like to decrease the process' virtual memory instead, turn off <code>-XX:-UseCompressedClassPointers</code>.</p>
