Skip to content

Large number of memfd:doublemapper (deleted) entries #89776

Open
@ayende

Description

@ayende

Description

When looking into our process, we noticed a large number of entries like this:

7fb3b0895000-7fb3b0896000 rw-s 03ac6000 00:01 2062                       /memfd:doublemapper (deleted)
7fb3b0896000-7fb3b08a0000 ---s 03ac7000 00:01 2062                       /memfd:doublemapper (deleted)
7fb3b08a0000-7fb3b08ab000 rw-s 03ad1000 00:01 2062                       /memfd:doublemapper (deleted)
7fb3b08ab000-7fb3b08b0000 ---s 03adc000 00:01 2062                       /memfd:doublemapper (deleted)
7fb3b08b0000-7fb3b08b9000 rw-s 03ae1000 00:01 2062                       /memfd:doublemapper (deleted)
7fb3b08b9000-7fb3b08c0000 ---s 03aea000 00:01 2062                       /memfd:doublemapper (deleted)
7fb427006000-7fb427007000 rw-s 00000000 00:01 2062                       /memfd:doublemapper (deleted)

The process has been running for about 8 hours, and we have:

sudo cat /proc/10459/maps | grep doublemapper | wc -l
3308

That number is not stable and grows over time, but we are just now loading data into the system, not yet trying to stress it.

Looking at the code, I found the source of that here:

int fd = memfd_create("doublemapper", MFD_CLOEXEC);

But looking at where this freed, I see:

close((int)(size_t)mapperHandle);

This looks like this will only actually be freed on MaxOS, and not on Linux?

FWIW, I couldn't find where this is called.

Is this number of entries expected? Should we monitor this value?
I understand that this is related to the way the JIT allocate memory?

Related, but we are seeing a large increase in memory usage in some production systems, which is not seen in .NET 6.0 but very noticeable in .NET 7.0

I noticed this:
#80580

And we are investigating whatever we do a lot of dynamic assembly generation (so far we don't think so, but can't rule it out).

Reproduction Steps

When I started writing this post, I had:

 sudo cat /proc/10459/maps | grep doublemapper | wc -l
3308

By the time I got here, I had:

sudo cat /proc/10459/maps | grep doublemapper | wc -l
3312

So I certainly think that there is something that work here.
Note that at this point, the process in question was running for hours, basically in a big loop. So there should be no change in behavior nor would I expect it to run any JIT tiering or some such.

Expected behavior

Not have the runtime allocate indefinitely memory

Actual behavior

We are seeing additional memory mapping over time

Regression?

Yes, we aren't seeing that in .NET 6.0

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions