Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct macOS Free and Available Memory #906

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

time-killer-games
Copy link
Contributor

@time-killer-games time-killer-games commented Dec 24, 2024

Based on my Godot pull request: godotengine/godot#100788

Code used is taken right out of Apple's official top(1) utility for macOS. Observing Apple's code at a first glance, it makes no sense why vmstat.free_count * pagesize would not be correct as that appears to be exactly what they are using to calculate free memory. However, I must be missing something, because vmstat.free_count * pagesize does not match the "unused memory" value shown when running top(1). It shows way less than that...

Instead, the correct value shown in top(1) corresponds to the value provided from how top(1) calculates used memory, while subtracting that from total memory. Makes no sense, I know. But this code is correct now and actually matches what is shown in top(1), which can be verified easily from testing if you like.

Edit:

I forgot how to squash commits, so please be patient with me while I try to figure that one out.

Edit 2:

I also have a system information utility I wrote which uses the same code underneath for RAM usage stats, as the code used in this pull request, in case you wanted something quick and easy to test and compare with top(1):

git clone https://github.com/time-killer-games/sysinfo $HOME/sysinfo && $HOME/sysinfo/build.sh

In this outdated screenshot you can see what free RAM used to look like back when I based it on vmstat.free_count * pagesize like you guys currently do:

macos

As you can see vmstat.free_count * pagesize is a lot smaller than what the actual free memory should reasonably be with only one app opened in the entire desktop. I highly doubt 260.39 MB free out of 8 GB of memory total is accurate given how little resources it takes to run that app.

Code used is taken right out of Apple's official [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433) utility for macOS. Observing Apple's code at a first glance, it makes no sense why `vmstat.free_count * pagesize` would not be correct as that appears to be exactly what they are using to calculate free memory. However, I must be missing something, because `vmstat.free_count * pagesize` does not match the "unused memory" value shown when running [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433). It shows *way* less than that...

Instead, the correct value shown in [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433) corresponds to the value provided from how [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433) calculates used memory, while subtracting that from total memory. Makes no sense, I know. But this code is correct now and actually matches what is shown in [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433), which can be verified easily from testing if you like.

Edit:

I forgot how to squash commits, so please be patient with me while I try to figure that one out.

Edit 2:

I also have a system information utility I wrote which uses the same code underneath for RAM usage stats, as the code used in this pull request, in case you wanted something quick and easy to test and compare with [top(1)](https://github.com/apple-opensource/top/blob/e7979606cf63270663a62cfe69f82d35cef9ba58/globalstats.c#L433):

```
git clone https://github.com/time-killer-games/sysinfo $HOME/sysinfo && $HOME/sysinfo/build.sh
```

In this outdated screenshot you can see what free RAM used to look like back when I based it on `vmstat.free_count * pagesize` like you guys currently do:

![macos](https://github.com/user-attachments/assets/a3dc259a-c01c-4dd0-b38a-c0211a4f0be8)

As you can see `vmstat.free_count * pagesize` is a lot smaller than what the actual free memory should reasonably be with only one app opened in the entire desktop. I highly doubt 260.39 MB free out of 8 GB of memory total is accurate given how little resources it takes to run that app.
@time-killer-games
Copy link
Contributor Author

Some interesting points were brought up in my pull request on fastfetch we might want to consider:

fastfetch-cli/fastfetch#1463 (comment)

top(1) is a part of the single unix specification

Which specification? I didn't find that in the list of standard POSIX commands

so it is more standardized in how it calculates these types of things, and in a way that will be cross-platform

It's not standardized. There is no standard to calcuate used memory bytes. In fact, it's also hard to define what is used (and free) memory. An Apple employee said that free memory is generally a nonsense value.

Note: the free memory is not memory physically not used at all (which is the value of free_count). For example, kernel usually caches loaded files to improve performance of future use, whose memory should not be considered as used because the memory can be dropped at any time.

Linux provides the standard free memory size, called MemAvailable, which defines free memory as the amount of memory that is available for a new workload, without pushing the system into swap. I doubt the accuracy of the value. For modern system supports memory compression, as the memory usage grows, much more cold memory data can be compressed. However before compression, I don't think there is a way to know how much memory can be actually saved by compressing. Therefore, as the author of MemAvailable said, it's still an estimation.

As there is no standard to calcuate used memory, you can't say a calcuation method is wrong, as long as it make sense somehow. Even Apple programs top and activity monitor can't agree with each other. top is available on some *nix platforms doesn't mean it is right.

Also wanted you to consider my response to them:

fastfetch-cli/fastfetch#1463 (comment)

I wanted to mention, how most platforms detect free memory is very different from how macOS does it and their official API's for doing this do in fact match what top shows for free memory even though macOS does not. As a result of most people using the official API's for this on their systems, programs like Godot, Redot, and even fastfetch are reporting the same thing for free memory that top is showing for unused memory on all platforms except macOS, I know this from my own testing. So I would say it would be better if macOS were consistent with other platforms and matched what top shows for unused memory. I even tested recently what fastfetch does on more obscure platforms like Solaris/illumos and it shows the same thing top does. Same also goes for used memory, most platforms besides macOS all these software are matching what top is showing.

I'll leave it up to you all if this approach is correct or not.

@tindrew
Copy link
Collaborator

tindrew commented Dec 25, 2024

Everyone is on a bit of a holiday break, but I'll make sure to get some eyes on this once it's over. Feel free to ping me (andevrs) on discord.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants