-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Use LibC.malloc instead of GC.malloc for external memory allocators #12451
Conversation
src/xml/libxml2.cr
Outdated
->(ptr) { GC.free(ptr) }, | ||
->(size) { GC.malloc(size) }, | ||
->(size) { GC.malloc(size) }, | ||
->(ptr, size) { GC.realloc(ptr, size) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused with these changes. Why they don't follow the same pattern as the others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried those, they produce a compiler error that I didn't understand 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> 2 | LibPCRE.pcre_malloc = ->LibC.malloc(LibC::SizeT)
^
Error: read before assignment to local variable 'arg0'
src/xml/libxml2.cr
Outdated
->(ptr) { GC.free(ptr) }, | ||
->(size) { GC.malloc(size) }, | ||
->(size) { GC.malloc(size) }, | ||
->(ptr, size) { GC.realloc(ptr, size) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot to change them to LibC 😊
Wouldn't this now exhaust the memory? I don't think we could really use while true
Regex.new(...)
end |
While I agree that the memory allocation should be performed outside of the GC's knowledge, |
Wow... I don't understand why this change makes |
PCRE does not perform automatic memory management on behalf of the user. |
For class Regex
def finalize
LibPCRE.free_study @extra
LibC.free @re.as(Void*) # <-- this is missing
end
end
LibPCRE.pcre_malloc = ->(size) { LibC.malloc(size) }
LibPCRE.pcre_free = ->(ptr) { LibC.free(ptr) }
# Or just don't set those functions, by default they will point to LibC.
# This is now fine:
while true
Regex.new("a|b")
end All those C libraries are, in theory, free of memory leaks if used properly. The wrappers around them must call the correct free function to ensure everything works. I think there is value on pursuing this. Not using the GC means less work being done. Probably a irrelevant amount of work though. |
Perhaps it's worth to reconsider it together with Guilherme's patch? |
I'm giving it a try.
|
Fixes #11614
There's no need to involve the GC when deciding how memory should be allocated and de-allocated for external libraries. If we use the GC it means that on a GC collect cycle that memory will have to be scanned for pointers... but that memory should never be automatically freed! So it's always better to allocate that memory outside of the GC's knowledge.