gnustep / libobjc2

Objective-C runtime library intended for use with Clang.
http://www.gnustep.org/
MIT License
434 stars 118 forks source link

Memory leak with @synchronized #98

Closed davidchisnall closed 5 years ago

davidchisnall commented 5 years ago

Simple test case:

#include "Test.h"
#include <sys/resource.h>
#include <stdio.h>

int main(void)
{
        for (int i=0 ; i<1000 ; i++)
        {
                for (int j=0 ; j<1000; j++)
                {
                        id obj = [Test new];
                        @synchronized(obj)
                        {
                        }
                        [obj dealloc];
                }
                struct rusage r;
                getrusage(RUSAGE_SELF, &r);
                printf("%ld\n", r.ru_maxrss);
        }
}

This should report a stable number for peak RSS, but instead it keeps increasing.

davidchisnall commented 5 years ago

This appears to be caused by adding the method to the dealloc method hidden class. Valgrind reports:

==77753==    at 0x4C245B5: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==77753==    by 0x4E4758C: class_addMethod (runtime.c:174)
==77753==    by 0x4E55610: initHiddenClassForObject (associate.m:239)
==77753==    by 0x4E54A94: referenceListForObject (associate.m:314)
==77753==    by 0x4E552A5: objc_sync_enter (associate.m:395)
davidchisnall commented 5 years ago

Fix also back-ported to the 1.9 branch.