RFR(M): 8152995: Solaris os::available_memory() doesn't do what we think it does

Daniel D. Daugherty daniel.daugherty at oracle.com
Wed Apr 6 16:31:58 UTC 2016


Thanks for adding Runtime to this discussion. The topic is definitely
of interest to Runtime folks...

More below...

On 2016-04-06 16:09, Erik Österlund wrote:
> Hi,
> Bug: https://bugs.openjdk.java.net/browse/JDK-8152995
> CR: http://cr.openjdk.java.net/~eosterlund/8152995/webrev.00/
> On Solaris, the os::available_memory() function is currently
> calculated with sysconf(_SC_AVPHYS_PAGES).

The Solaris man page for sysconf(_SC_AVPHYS_PAGES):

_SC_AVPHYS_PAGES  Number of physical memory pages not
                   currently in use by system

> Unfortunately this does not match intended semantics. The intended
> semantics is to return how much memory can be allocated by mmap into
> physical memory. But, what _SC_AVPHYS_PAGES does is to return how many
> physical pages are available to be used by virtual memory as backing
> storage on-demand once it is touched, without any connection
> whatsoever to virtual memory.

This part has me curious:

 > The intended semantics is to return how much memory can be allocated
 > by mmap into physical memory.

since I don't understand where you found the "intended semantics".

Only one of the platforms has any comments about available_memory:


// available here means free
julong os::Bsd::available_memory() {

the rest just don't say...

Personally, I've always interpreted available_memory() to mean
available physical pages, as in pages that are not in use now.
This matches the definition of _SC_AVPHYS_PAGES above...

> Even if we mmap to commit heap memory without NORESERVE, the
> _SC_AVPHYS_PAGES metric does not change its value - at least not until
> somebody actually touches the mmaped memory and it starts becoming
> backed by actual physical memory. So the JVM can in theory commit the
> whole physical memory, and _SC_AVPHYS_PAGES will still reply that all
> that memory is still available given that it has not been touched yet.

Yes, I believe that is exactly how things work and I think
that available_memory() is returning that information

> It is likely that this is related to random swap-related test
> failures, where too many JVMs are created based on this metric.

Please explain further. What do you mean by "too many JVMs are
created based on this metric"?

> Even
> if it is not, the os::available_memory() call is still broken in its
> current state and should be fixed regardless.

I'm not yet convinced that available_memory() is broken
and needs to be fixed. I don't see available_memory() being
used in a lot of places and those uses that I do see are
mostly just reports of the value...

So what am I missing about how os::available_memory() is
being used?


> My proposed fix uses kstat to get the available memory that can be
> mmapped (which actually relates to virtual memory). It then uses
> swapctl() to find out the amount of free swap, subtracting that from
> the kstat value, to make sure we do not count swap memory as being
> available for grabbing, to mimick the current behaviour of other
> platforms. The code iterates over the potentially many swap resources
> and adds up the free swap memory.
> kstat gives us all memory that can be made available, including memory
> already used by the OS for things like file caches, and swap memory.
> When this value is 0, mmap will fail. That's why I calculate the
> amount of swap and remove that, assuming it is okay to use memory that
> isn't immediately available but can be made available, as long as it
> does not involve paging to the swap memory.
> Testing:
> * JPRT
> * Made my own test program that can be found in the comments of the
> BUG to report on memory values, so I could verify what is going on and
> that when the new os::available_memory() becomes 0, is indeed when
> paging to swap starts happening using vmstat.
> I need a sponsor to push this if anyone is interested.
> Thanks,
> /Erik

More information about the hotspot-gc-dev mailing list