Hermes: Introduce explicit "commit" in OSCompat abstraction of virtual memory

Created on 18 Mar 2019  路  6Comments  路  Source: facebook/hermes

To start, read the attached picture to understand how the basics of memory allocation works in POSIX and Windows.

The cause of the problem is the transition from Reserved to Committed. On POSIX, it is implied. As a result, in Hermes code, there isn't a call that explicitly does that.

A shortcut was taken in my initial Windows port:

  • oscompat::vm_allocate on Windows returns memory that has been Committed.
  • oscompat::vm_unused does nothing.

For context, the point of vm_unused is to free the physical memory (but not virtual address space), and so that it doesn't count against our RSS. (Please correct me if this understanding is incorrect.)

The goal of this issue is:

  • Add vm_commit (MEM_COMMIT on Windows, no-op on posix)
  • Change vm_allocate to reserve the memory without committing it (MEM_RESERVE on Windows, no change needed on posix)
  • Implement vm_unused with MEM_DECOMMIT on Windows.
  • Change relevant code that interacts with vm_* so that they invoke vm_commit before accessing the memory if vm_commit has not been invoked since the latest vm_allocate and vm_unused.

50932988_366403384141481_1486283032032706560_o

Tracked as T40416012 at Facebook.

enhancement

Most helpful comment

To expand on what @tmikov commented.

With NCGen, Hermes reserves memories as 4MB segments. The expected outcome of this issue is not to break down the 4MB at commit time. In fact, I expect "commit" to still happen 4MB at a time. Instead, it is so that vm_unused can have meaningful impact (to reduce RSS) on Windows.

All 6 comments

As part of this task, once vm_unused is implemented, tests that exercised vm_unused can be re-enabled. However, those tests also exercises regionFootprint, which is a test-only function that isn't implemented for Windows. regionFootprint is certainly implementable on Windows.

  • Microsoft Sysinternals provide a tool called VMMap, which provides the same kind of info that /proc/self/smaps provides. Screenshot here.
  • An open source command line equivalent of VMMap can be found by following links in this stackoverflow question.
  • Look for QueryWorkingSet in process_map.cpp in twpol/vmmap.

I think it is very important to note that Hermes is committing incrementally on Windows, only it is happening with a granularity of a single segment (4MB).

To expand on what @tmikov commented.

With NCGen, Hermes reserves memories as 4MB segments. The expected outcome of this issue is not to break down the 4MB at commit time. In fact, I expect "commit" to still happen 4MB at a time. Instead, it is so that vm_unused can have meaningful impact (to reduce RSS) on Windows.

Thanks for the clarification. I haven't tested with NCGen yet.
vm_unused implementation would help for long running apps.

@mganandraj After a full GC we release unused 4MB segments to the OS, so you will get that behavior already, with 4 MB granularity.

I think this will actually be more relevant if PreAllocatedStorageProvider is used instead of VMAllocateStorageProvider.

PreAllocatedStorageProvider right now (on Windows) will reserve and commit the whole 500 MB range; however, it could be changed to only reserve the 500 MB range, and commit upon each call to newStorage.

PreAllocatedStorageProvider isn't the default yet for NCGen, but providing some experiments I'm working on go well, we might transition to using that on some platforms.

Was this page helpful?
0 / 5 - 0 ratings