How Kotlin/Native garbage collector works in C? - c

I'm found some explanation of Kotlin/Native memory management model in JetBrains FAQ.
A: Kotlin/Native provides an automated memory management scheme,
similar to what Java or Swift provides. The current implementation
includes an automated reference counter with a cycle collector to
collect cyclical garbage.
I understand more or less how it works in Java or Kotlin (JVM). Can any describe detailed how memory is managed in Kotlin/Native in projects with C?
Also, if there is the garbage collector, why do we need a Kotlin/Native function memScoped { }?
Also, I found here :
Kotlin/Native is a technology for compiling Kotlin to native binaries that run without any VM.
Broadly speaking, Native code is any code whose memory is not managed by the underlying framework but has to be managed by the programmer themselves. i.e. there is no Garbage collection.
e.g. C++’ delete and C’s free
which in my opinion contradicts what is written in JetBrains FAQ

Memory Management in K/N is provided by the runtime. It consists of two main parts: automatic reference counting and cycle collector. This provides one with availability to write the code just as in the Kotlin/JVM. Some details on this topic can be found digging inside this file but all you need to know is that it is automatic by default.
About MemScoped etc. When you use interoperability with C, you have to deal with managing such a resource as native memory. Native memory is the memory provided to the application process by the operating system. As it has nothing to do with the Kotlin code, this resource can't be managed by K/N runtime. But all C struct s and variables you are going to use must be allocated there. You can do it straight by calling nativeHeap.alloc() function. When the need of this memory is gone, it can be freed by nativeHeap.free().
But to make your experience more comfortable, K/N also has Arena class, implementing region-based memory management. It simplifies memory management to just a series of alloc() wherever you need, and one deallocation by .clear() for all the region.
Also, there is a MemScoped {} blocks, that covers Arena from you, and lets to forget about even the freeing native memory. So in your code that includes some elements from C, you can just write MemScoped { ... }, and then put operations into it. You can see a lot of examples of this approach in the samples from the K/N repository

Related

Real-World Dangers of C Memory Leaks?

I am learning C, and am concerned about memory leaks. I understand that rebooting will generally flush memory, and assuming I don't run the program again, I will be fine. I am considering using a second, high-power machine. How badly can I screw up my system if:
I do something ridiculously stupid
I use GCC (not sure if the compiler can do anything?)
I have a memory leak and restart
Out of curiosity, if I used a VM. I probably won't, because I simply prefer using real hardware.
Would any of the following things have long-term effects on my system? Thanks.
If your product is pure software, the biggest thing that you have to worry about is a memory leak building up and eventually causing the machine to run out of memory, fail to allocate any more, and the application will crash. A lot of memory won't be happening repeatedly and won't even get this far. They will then go away when the application exits. Your application could also potentially corrupt data if something is being modified when it crashes, but that could apply to any type of crash.
If your product controls hardware in some way, you need to be very careful. If the software fails, then you don't know what the hardware may do. As one of the comments said, a spaceship with a memory leak that causes it to crash can make the spaceship crash. Robots could move unexpectedly and cause damage to property or injury to people. Other devices could cause electrical discharges.
As far as handling memory leaks, you just have to be careful. In C, any call to malloc and similar functions needs to be paired with a call to free on all paths of execution. If some type of error occurs, free still needs to be called if the application is going to continue running. Likewise, fopen should be paired with fclose. Here, you can also run into issues with running out of file handles, which is a different but similar problem in many ways. In C++, manual memory allocation with new should be paired with delete, although using "smart" pointers like std::unique_ptr, std::shared_ptr, and std::weak_ptr can ease memory management and prevent memory leaks. Other libraries also provide pointer types that use reference counting to handle their own lifecycle. I would recommend using these any time you can over raw pointers. If you have the option to use C++ instead of C, I would also recommend that. In most cases (performance or otherwise), you don't really need C over C++. If you're not sure that you need C, you can probably use C++.
If you're interested in finding memory leaks, check out valgrind. It has a lot of functionality that will help you find memory leaks and determine their severity.
Memory leaks won't damage your machine. When a program terminates, all of its transient resources are released, including whatever memory was allocated to it.
What will suffer is your programming style. Correctly freeing resources is not difficult, but it takes some practice. After a while, you will need to think much less in order to do it. And that is one of the things that makes you a good programmer.
Why does it matter? Because sooner or later, you will start writing programs that run for a long time, perhaps an information server, or a web browser, or a graphic editor. Something that stays active until the user no longer needs it, or because it crashes after using up all available memory. And you don't want to be responsible for the second outcome.
So right now, when you're starting, is the time to develop some good habits. Learn how to do it right, and you won't have to relearn it later.
According to the answers in the comments:
Memory leaks should go away if the system restarts
Spaceships are hard to reboot
VMs are safe if they are written properly
Thanks for the quick answers!

Disable __thread support

I'm implementing a pthread replacement library which is extremely lightweight. There are several reasons why I want to disable __thread completely.
It's a waste of memory. If I'm creating a thousand threads which has nothing to do with the context that declares a variable with __thread they will still allocate the program will still have allocated 1000*the size of that data bytes and never use it. It's simply not memory compatible with the mass-concurrency model. If we need extremely lightweight fibers with only 8K of stack, a TLS block of just 4K would be an overhead of 50% of the memory used by each thread. In some scenarios the TLS overhead would be enormous.
TLS is a complex standard and I simply don't have the time/resources to support it. It's to expensive. Personally I think the standard is poorly designed. It should have defined standard functions that had to be provided by the linker so thread libraries can take control over where TLS allocation takes place and insert relevant offsets and addresses it requires. Also the standard ELF implementation has been infected with pthread, expecting pthread sized structs to calculate offsets making it really hard to adapt to something else.
It's just a bad pattern. It encourages using globals and creating functions with static functions/side effects. This is not a territory we want to be in if we're creating correct programs that are easy to analyze.
If we really need "thread context" for some magic that tracks thread state behind the scenes (like for allocation or cancellation tracking) why not just expose the magic that TLS uses to understand that context in the first place? Personally I'm just going to use the %fs register directly. This would not be possible in libraries for obvious reasons but why should they be thread aware to begin with? Why not just design them correctly so they get the context related data they need in the first place right in the argument list?
My question is simply: What is the simplest way to disable __thread support and make clang emit errors if you accidentally used it? How can I get errors if I load a dynamic library which happens to require TLS?
I believe the simplest way is adding something like this unconditionally to your CFLAGS (perhaps from clang's equivalent of the gcc specfile if you want it to be system-global):
-D__thread='^-^'
where the righthand side can be anything that's syntactically invalid (a constraint violation) at any point in a C program.
As for preventing loading of libraries with TLS, you'd have to patch the linker and/or dynamic linker to reject them. If you're just talking about dlopen, your program could first read the file and parse the ELF headers for TLS relocations, then reject the library (without passing it to dlopen) if it has any. This might even be possible with an LD_PRELOAD wrapper.
I agree with you that, especially in its current implementation, TLS is something whose use should generally be avoided, but may I ask if you've measured the costs? I think stamping it out completely will be fairly difficult on a system that's designed to use it, and there's much lower-hanging fruit for cutting bloat. Which libc are you using? If it's glibc, I'm pretty sure glibc has lots of TLS it uses internally itself these days... Of course if you're writing your own threads implementation, that's going to entail a lot of interaction with the rest of the standard library, so perhaps you're already patching it out...?
By the way (shameless plug follows), we have an extremely light-weight threads implementation in musl libc which presently does not have TLS. I don't think it would be easy to integrate with another libc (and I'm sure if you're writing your own you will find it difficult to integrate with glibc, especially glibc's dynamic linker, which expects TLS to be supported) but if you can use the whole library as-is, it may meet your needs for specific projects, or have useful code you can borrow (license is MIT).

Seeking deeper understanding of Visual Studio C-runtime library link behavior

This is something I've just blindly accepted and followed as "the way it is". I'm trying to gain a deeper understanding of the "why" behind it.
static library LibA - utulizes some C runtime calls
static library LibB - utilizes some C runtime calls
executable App - utilizes LibA, LibB, and some C runtime calls
It is pretty well documented here and a bunch of other places that all modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option.
If all symbol resolution is performed during the final link for App as discussed here and here, why is this the case? Why do LibA and LibB even need to specify a specific runtime library to use when they build? Shouldn't the C runtime calls they use just resolve against whatever runtime App specifies for its link?
Is this an issue in other C development environments or is it specific to Visual Studio?
As Hans Passant mentioned in his comment, there are some global state items that have to change between a DLLs runtime and a static link runtime. Even worse than his example is when the size of a type changes based upon which runtime created it. However, there are a few more reasons:
Debug vs Release:
The debug runtimes will place guard bytes surrounding dynamically allocated memory. This allows their memory allocation and freeing code to do extra checks to help you find memory problems such as double-frees and writing outside your allocated buffers. The release runtimes don't don't use the extra checks in favor of optimization. Therefore, if memory is allocated with one and freed with another, you may get unpredictable results.
DLL vs static linkage:
In Windows, the rule of thumb is that you must free memory in the same module which you allocated it. In other words, if you allocated memory in msvcrt.dll, you must also free it there. Therefore, if some parts of an application link to a static runtime and some link to a runtime DLL, this rule may be violated. When this happens, you can also get unpredictable results including exceptions.
Multithread vs Singlethread:
The potential for conflicts between these 2 runtime types should be obvious. The single threaded version isn't thread safe, so mixing it with something expecting thread safety will make for interesting debugging later. This distinction is largely only present in the older MS compilers since the only option is multithreaded in newer releases.
See also this similar question: Mixing Static Libraries of C Code built from different versions of Visual Studio 2002 and later

Should a C library offer ability to use custom memory allocators?

I see that some C libraries have ability to specify custom memory allocators (malloc/free replacements).
In what systems/environments/conditions is that useful? Isn't this feature just a leftover from MSDOS era or similar no-longer-relevant problems?
Background story:
I'm planning to make pngquant a library that can be embedded in various software (from iOS apps to Apache modules). I'm using malloc()/free() and my own memory pools for small allocations. I use 2MB-50MB of memory in total. I use threads, but only need to alloc on the main thread.
In any application where control over memory allocation is critical (for example my field, game development, or other real or near real time systems) the inability to control memory allocations in a library immediately disqualifies it from use.
Many malloc/free algorithms exist. The system malloc is sometimes not optimized for the task that the library is handling, so the caller might want to try a few different ones to optimize performance.
A few that come to mind are:
dlmalloc
jemalloc
TCMalloc
There are also Garbage Collection libraries such as the Boehm Garbage Collector which are usable in C by calling the provided malloc/free replacements (even though free is then a dummy function call, kept for compatibility).
There are also many possible uses, for example one may write a debug malloc/free function that could trace memory allocations and liberations in the library, such as one that I wrote that uses SQLite to record statistics about how the memory is used (admittedly at the cost of performance, but it is a debugging situation).

Generational GC source code

I am studying GC implementations, and I'm currently looking for references and good open-source GC examples to base in.
Is there any good and simple generational GC implementation ? The second best thing would be good resources and guidelines!
Thank you!
I've wrote the Qish garbage collector (not really maintained any more, but feel free to ask). It is a free copying generational GC for C (with some coding styles restrictions).
The GCC MELT [meta-]plugin (free, GPLv3 licensed), providing a high level language, MELT, to extend the GCC compiler, also has a copying generational GC above the existing Ggc garbage collector of GCC. Look into gcc/melt-runtime.c
With generational copying GC, generating the application's code in C is quite useful. See my DSL2011 paper on MELT
Feel free to ask me more, I love talking about my GC-s.
Of course, reading the Garbage Collection Handbook: The Art of Automatic Memory Management (Jones, Hosking, Moss) [ISBN-13: 978-1420082791] is a must
(added in 2017)
Look also into Ravenbrook's Memory Pool System which can be used for generational GC.
Look also into the runtime of Ocaml, which has a good (single-threaded) generational GC.
PS. Debugging a generational copying GC is painful.
Java's HotSpot GC
You can look at the various GC implementations provided by the JVM here.
The Memory Management white paper gives an overview of the different garbage collectors implemented in the JVM. Its from 2006 so its missing the new G1 collector details but its a good starting point.
Mon's SGen GC
Mono's new SGen is on github too. Check out the sgen files.
The Ovm framework is open source and offers a framework that allows to select several features regarding garbage collection for real-time systems.
According to the website
Includes Minuteman RTGC framework which allows to select from newly
supported RTGC features: time-based scheduling (periodic, slack, and
hybrid - a combination of both), incremental stack scanning,
replication or Brooks barrier, incremental object copy, arraylets,
memory usage, and GC pause profiling and tracing.
Although domain specific, it may be a good starting point for your study.
I hope this helps.
The V8 project (Javascript engine used in Chrome and Android) is open source and has a simple generational garbage collector.
You can browse the source code online. In particular, look at heap.cc (implementation of the heap and scavenge algorithm), spaces.cc (lower level heap stuff), and mark-compact.cc (full garbage collector).
The Parrot VM also uses a generational garbage collector.
Although it's not in written in C, the JikesRVM JVM contains several GC implementations, including a couple of generational ones, and I think it's rather simple to understand.
The Boehm Garbage Collector is commonly used for C and C++ projects.

Resources