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

Very poor GC memory utilization due to fragmentation #17471

Open
dlangBugzillaToGithub opened this issue Jan 11, 2024 · 1 comment
Open

Very poor GC memory utilization due to fragmentation #17471

dlangBugzillaToGithub opened this issue Jan 11, 2024 · 1 comment
Labels
Druntime:GC Issues relating the Garbage Collector Druntime Specific to druntime OS:Linux P1 Severity:normal

Comments

@dlangBugzillaToGithub
Copy link

Vladimir Panteleev (@CyberShadow) reported this on 2024-01-11T10:07:12Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=24328

Description

This program seems to be able to utilize only 2% of memory available to it - the rest seems to be wasted by fragmentation:

///////////////////////////////// test.d ////////////////////////////////
import core.stdc.stdio;
import core.stdc.stdlib;

enum size_t memoryLimit = 1UL * 1024 * 1024 * 1024;
enum size_t allocationSize = 64;

void main()
{
    {
        import core.sys.posix.sys.resource :
            rlimit, RLIMIT_AS, getrlimit, setrlimit;
        rlimit lim;
        getrlimit(RLIMIT_AS, &lim);
        lim.rlim_cur = memoryLimit;
        setrlimit(RLIMIT_AS, &lim);
    }

    // Size of reachable data created by this function
    size_t utilizedSize;

    scope(exit) printf("Utilized size: %zu (%zd%%)
",
        utilizedSize, utilizedSize * 100 / memoryLimit);

    ubyte[][] pinned;
    int n;
    while (true)
    {
        ubyte[] arr;
        {
            scope(failure) printf("Failed to allocate %zu
",
                allocationSize);
            arr = new ubyte[allocationSize];
        }
        bool keep = n++ % 2 == 0;
        if (keep)
        {
            {
                scope(failure) printf("Failed to reallocate %zu bytes
",
                    (pinned.length + 1) * pinned[0].sizeof);
                pinned ~= arr;
            }
            utilizedSize += allocationSize + pinned[0].sizeof;
        }
    }
}
/////////////////////////////////////////////////////////////////////////
@dlangBugzillaToGithub
Copy link
Author

dlang-bugzilla (@CyberShadow) commented on 2024-01-11T10:24:16Z

If I modify the program to use C malloc/free instead of the D GC, I get 81% utilization:

////////////////////////// test_c.d //////////////////////////
import core.stdc.stdio;
import core.stdc.stdlib;

enum size_t memoryLimit = 1UL * 1024 * 1024 * 1024;
enum size_t allocationSize = 64;

@nogc
void main()
{
    {
        import core.sys.posix.sys.resource :
            rlimit, RLIMIT_AS, getrlimit, setrlimit;
        rlimit lim;
        getrlimit(RLIMIT_AS, &lim);
        lim.rlim_cur = memoryLimit;
        setrlimit(RLIMIT_AS, &lim);
    }

    // Size of reachable data created by this function
    size_t utilizedSize;

    scope(exit) printf("Utilized size: %zu (%zd%%)\n",
        utilizedSize, utilizedSize * 100 / memoryLimit);

    void** pinned; size_t numPinned;
    int n;
    while (true)
    {
        void* arr = malloc(allocationSize);
        if (!arr)
        {
            printf("Failed to allocate %zu\n",
                allocationSize);
            return;
        }
        bool keep = n++ % 2 == 0;
        if (keep)
        {
            auto newSize = (numPinned + 1) * pinned[0].sizeof;
            pinned = cast(void**)realloc(pinned, newSize);
            if (!pinned)
            {
                printf("Failed to reallocate %zu bytes\n",
                    (numPinned + 1) * pinned[0].sizeof);
                return;
            }
            pinned[numPinned++] = arr;
            utilizedSize += allocationSize + pinned[0].sizeof;
        }
        else
            free(arr);
    }
}
//////////////////////////////////////////////////////////////

@thewilsonator thewilsonator added Druntime Specific to druntime Druntime:GC Issues relating the Garbage Collector and removed Arch:x86_64 Issues specific to x86_64 labels Dec 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Druntime:GC Issues relating the Garbage Collector Druntime Specific to druntime OS:Linux P1 Severity:normal
Projects
None yet
Development

No branches or pull requests

2 participants