How to turn off the GC in Crystal and do memory management yourself, without any GC? - crystal-lang

I'm evaluating the Crystal programming language for real-time, low-latency applications, that can't be interrupted by the garbage collector.
Two questions:
Is it possible to deallocate some class from the heap? For example, in the loop below:
while true
p = Person.new
# do stuff with p
free p # <-------- HERE
end
Is there a flag like -verbose:gc in Java, that allows us to see everything the GC is doing?
Cheers!

You can free any heap allocated memory with GC.free. This is unsafe and potentially dangerous, which you surely are aware of.
Crystal uses BDWGC, so you can use its runtime configuration options (such as GC_PRINT_STATS) to enable logging.
If you want, you can entirely disable the garbage collector by passing the -Dgc_none flag. But the entire standard library assumes to be used with garbage collection and does not do any manual memory management. So if you use stdlib, it will inevitably pile up heap memory.

Related

About Memory Management When mentioning C++

When someone mention the memory management the c++ is capable of doing, how can i see this thing? is this done in theory like guessing?
i took a logical design intro course and it covered the systems of numbers and boolean algebra and combinational logic,will this help?
so say in Visual Studio , is there some kind of a tool to visualize the memory,i hope im not being ridiculous here ?
thank you.
C++ has a variety of memory areas:
space used for global and static variables, which is pre-allocated by the compiler
"stack" memory that's used for preserving caller context during function calls, passing some function arguments (others may fit in CPU registers), and local variables
"heap" memory that's allocated using new or new[](C++'s preferred approach) or malloc (a lower-level function inherited from C), and released with delete, delete[] or free respectively.
The heap is important in that it supports run-time requests for arbitrary amounts of memory, and the usage persists until delete or free is explicitly used, rather than being tied to the lifetime of particular function calls as per stack memory.
I'm not aware of any useful tools for visualising and categorising the overall memory usage of a running C++ program, less still for relating that back to which pointers in the source code currently have how much memory associated with them. As a very general guideline, it's encouraged to write code in such a way that pointers are only introduced when the program is ready to point them at something, and they go out of scope when they will no longer pointer at something. When that's impractical, it can be useful to set them to NULL (0), so that if you're monitoring the executing program in a debugger you can tell the pointer isn't meant to point to legitimate data at that point.
Memory management is not something that you can easily visualize while you are programming. Instead, it refers to how your program is allocating and freeing memory while it is running. Many debuggers will provide a way to halt a program while it is running and view information about the dynamic memory that it has allocated. You can plan your classes and interfaces with proper memory management techniques, but it's not as simple as "hit this button for a chart of your memory usage".
You can also implement something like this to keep track of your memory allocations and warn you about anything that your program didn't free. A garbage collector can free you from some of the hassles associated with memory management.
In Visual Studio, there is a Memory Window (Alt+6) that will let you read/write memory manually provided it is a valid memory location for the operation you are trying to do, during debugging.
On Windows platform, you can get a first initial feel of memory management using tools like perfmon.exe, taskmgr.exe and many other tools from sysinternals

What is the philosophy of managing memory in C++? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
What is the design factor in managing memory in C++?
For example: why is there a memory leak when a program does not release a memory object before it exits? Isn't a good programming language design supposed to maintain a "foo-table" that takes care of this situation ? I know I am being a bit naive, but what is the design philosophy of memory management in C++ with respect to classes, structs, methods, interfaces, abstract classes?
Certainly one cannot humanely remember every spec of C++. What is the core driving design of memory management?
What is the core driving design of memory management ?
In almost all cases, you should use automatic resource management. Basically:
Wherever it is practical to do so, prefer creating objects with automatic storage duration (that is, on the stack, or function-local)
Whenever you must use dynamic allocation, use Scope-Bound Resource Management (SBRM; more commonly called Resource Acquisition is Initialization or RAII).
Rarely do you have to write your own RAII container: the C++ standard library provides a whole set of containers (e.g., vector and map) and smart pointers like shared_ptr (from C++ TR1, C++0x, and Boost) work very well for most common situations.
Basically, in really good C++ code, you should never call delete yourself1 to clean up memory that you've allocated: memory management and resource cleanup should always be encapsulated in a container of some kind.
1. Obviously, the exception here is when you implement an RAII container yourself, since that container must be responsible for cleaning up whatever it owns.
It's not entirely clear whether you're asking about the philosophy of what's built into C++, or how to use it in a way that prevents memory leaks.
The primary way to prevent memory leaks (and other resource leaks) is known as either RAII (Resource Acquisition Is Initialization) or SBRM (Scope Bound Resource Management). Either way, the basic idea is pretty simple: since objects with auto storage duration are automatically destroyed on exit from their scope, you allocate memory in the ctor of such an object, and free the memory in its dtor.
As far as C++ itself goes, it doesn't really have a philosophy. It provides mechanisms, but leaves it up to the programmer to decide which mechanism is appropriate for the situation at hand. That's often RAII. Sometimes it might be a garbage collector. Still other times, other times it might be various sorts of custom memory managers. Of course, sometimes it's a combination of two or all three of those, or something else entirely.
Edit: As to why C++ does things this way, it's fairly simple: almost any other choice will render the language unsuited to at least some kinds of problems -- including a number for which C++ was quite clearly intended to be suitable. One of the most obvious of these was being able to run on a "bare" machine with a minimum of support structure (e.g., no OS)
C and C++ take the position that you, the programmer, know when you are done with memory you have allocated. This avoids the need for the language runtime to know much of anything about what has been allocated, and the associated tasks (reference counting, garbage collection, etc.) needed to "clean up" when necessary.
At the crux is the idea that: if you allocate it, you must free it. (malloc/free, new/delete)
There are several methods of helping manage this so that you don't have to explicitly remember. RAII and the smart pointer implementations that provide containers that do it is extremely useful and powerful for managing memory based on object creation and destruction. They will save you hours of time.
why is there a memory leak when a program does not release a memory object before it exits ?
Well, the OS typically clean up your mess for you. However, what happens when your program is running for an arbitrary amount of time and you have leaked so much memory that you can't allocate anymore? You crash, and that's not good.
Isn't a good programming language design supposed to maintain a "foo-table" that takes care of this situation ?
No. Some programming languages have automated memory management, some do not. There are benefits and drawbacks to both models. Languages with manual memory management allow you to say when and where resources are allocated and released, i.e., it is very deterministic. A relative beginner will however inevitably write code that leaks while they are getting used to dealing with memory management.
Automated schemes are great for the programmer, but you don't get the same level of determinism. If I am writing a hardware driver, this may not be a good model for me. If I were writing a simple GUI, then I probably don't care about some objects persisting for a bit longer than they need to, so I will take an automated management scheme every time. That's not to say that GC'd languages are only for 'simple' tasks, some tasks just require a tighter control over your resources. Not all platforms have 4GB+ memory for you to play around in).
There are patterns that you can use to help you with memory management. The canonical example would be RAII (Resource Allocation is Initialization)
Philosophy-wise, I think there are two things that lead to C++ not having a garbage collector (which seems to be what you're getting at):
Compatibility with C. C++ tries to be very compatible with C, for better or worse. C didn't have garbage collection, so C++ doesn't, at least not by default. I guess you could sum this up as "historical reasons".
The "you only pay for what you use" philosophy. C++ tries to avoid imposing any overhead above C unless you explicitly ask for it. So you only pay the price of exceptions if you actually throw one, etc. There's an argument that garbage collection would impose a cost whenever an object is allocated on the heap so it couldn't be the default behavior in C++.
Note that there is actually quite a bit of debate about whether garbage collection is actually more or less efficient than manual memory management. The better garbage collectors generally want to be able to move stuff around though, and C++ has pointer arithmetic (again, inherited from C) that makes it very hard to make such a collector work with C++.
Here's Stroustrup's (not really direct) answer to "Why doesn't C++ have garbage collection?":
If you want automatic garbage collection, there are good commercial and public-domain garbage collectors for C++. For applications where garbage collection is suitable, C++ is an excellent garbage collected language with a performance that compares favorably with other garbage collected languages. See The C++ Programming Language (3rd Edition) for a discussion of automatic garbage collection in C++. See also, Hans-J. Boehm's site for C and C++ garbage collection.
Also, C++ supports programming techniques that allows memory management to be safe and implicit without a garbage collector.
C++0x offers a GC ABI.
Isn't a good programming language design supposed to maintain a "foo-table" that takes care of this situation ?
Is it? why? A good programming language is one that lets you solve problems, no more, no less.
A garbage collector certainly lowers the barrier of entry, but it also takes control away from the programmer, which might be a problem in some cases. True, on a modern 2.5GHz quad-core computer, and with today's advanced and efficient garbage collectors, we can live with that. But C++ had to work with much more limited hardware, ranging from desktop computers with a whopping 16MB of RAM down to embedded platforms with 16KB, and everything in between. It has to be usable in realtime code, where you can not just pause the program for 0.5 seconds to run a garbage collection.
C++ isn't just designed to be the language used on desktop computers. It's meant to be usable everywhere, on memory-limited systems, in hard realtime scenarios, on large supercomputers and everywhere else.
C++'s guiding principle is "you don't pay for what you don't use". If you don't want a garbage collector, you shouldn't have to pay the (steep) price of one.
There are very powerful techniques to manage memory in C++ and avoid memory leaks, even without a garbage collector. If a garbage collector was the only way to avoid memory leaks, then there'd be a strong argument in favor of adding one to the language. But it isn't. You just have to learn how to properly manage memory yourself in C++.
What is the core driving design of memory management?
The driving design (no pun intended) is a bit like that of stick-shift transmission cars, as opposed to automatic transmission cars. Like a stick-shift car, C++ gives you freedom and control over the machine, but it's not as easy to use as automatic ones that take care of many things for you.
The following could easily have been written about C++ versus Java:
People who drive stick shift cars know the difference and the advantages of
having total control of your car engine; people who drive cars with automatic
transmissions do not. (...) Race cars, for example, do not use automatic
transmissions. (...) People who are used to shifting gears will focus more
on their driving making it more efficient and safe.
http://www.eslbee.com/contrast_stick_shift_or_automatic.htm
I should add, though, that C++ does have some mechanism that handle the memory for you, like others have mentioned, e.g. RAII, smart pointers etc.
C++ has no design philosophy wrt memory. All it has are two functions for allocating memory (new malloc) and two functions for freeing memory ( delete free ) and a frew related functions. Even those can be replaced by the programmer.
This is because C++ aims to run on generic computers. Generic computers are a CPU, memory (RAM, varieties of ROM) and a bus/busses for peripherals. There is no built in memory management on generic computers.
Now most computers come with memory ( typically a ROM variant ) which contains a bios/monitor. There you might see some rudimentary form of memory management --probably not.
Some computers come with OSes which will have memory management, but even there it is often primitive, and it is easy for me to claim that most computers running a C++ program have no OS at all.
If you expect C++ to run on any computer, it cannot have a memory management philosophy.

How are malloc and free implemented?

I want to implement my own dynamic memory management system in order to add new features that help to manage memory in C++.
I use Windows (XP) and Linux (Ubuntu).
What is needed to implement functions like 'malloc' and 'free'?
I think that I have to use lowest level system calls.
For Windows, I have found the functions: GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy and HeapFree.
For Linux, I have not found any system calls for heap management. On Linux, malloc and free are system calls, are not they?
Thanks
Edit:
C++ does not provide garbage collector and garbage collector is slow. Some allocations are easy to free, but there are allocations that needs a garbage collector.
I want to implement these functions and add new features:
* Whenever free() be called, check if the pointer belongs to heap.
* Help with garbage collection. I have to store some information about the allocated block.
* Use multiple heaps (HeapCreate/HeapDestroy on Windows). I can delete an entire heap with its allocated blocks quickly.
On linux, malloc and free are not system calls. malloc/free obtains memory from the kernel by extending and shrinking(if it can) the data segment using the brk system calls as well as obtaining anonymous memory with mmap - and malloc manages memory within those regions. Some basic information any many great references can be found here
In *nix, malloc() is implemented at the C library level. It uses brk()/sbrk() to grow/shrink the data segment, and mmap/munmap to request/release memory mappings. See this page for a description of the malloc implementation used in glibc and uClibc.
If you are simply wrapping the system calls then you are probably not gaining anything on using the standard malloc - thats all they are doing.
It's more common to malloc (or HeapAlloc() etc ) a single block of memory at the start of the program and manage the allocation into this yourself, this can be more efficient if you know you are going to be creating/discarding a lot of small blocks of memory regularly.
brk is the system call used on Linux to implement malloc and free. Try the man page for information.
You've got the Windows stuff down already.
Seeing the other answers here, I would like to note that you are probably reinventing the wheel; there are many good malloc implementations out there already. But programming malloc is a good thought exercise - take a look here for a nice homework assignment (originally CMU code) implementing the same. Their shell gives you a bit more than the Linux OS actually does, though :-).
garbage collector is slow
This is a completely meaningless statement. In many practical situations, programs can get a significant performance boost by using a Garbage Collector, especially in multi-threaded scenarios. In many other situations, Garbage Collectors do incur a performance penalty.
Try http://www.dent.med.uni-muenchen.de/~wmglo/malloc-slides.html for pointers.
This is a brief performance comparison, with pointers to eight different malloc/free implementations. A nice starting point, because a few good reference statistics will help you determine whether you've improved on the available implementations - or not.

Why C/C++ have memory issue?

I have read lots of programmers saying and writing when programming in C/C++ there are lots of issue related to memory. I am planning to learn to program in C/C++. I have beginner knowledge of C/C++ and I want to see some short sample why C/C++ can have issues with memory management. Please Provide some samples.
There are many ways you can corrupt or leak memory in C or C++. These errors are some of the most difficult to diagnose, because they are often not easily reproducible.
For example, it is simple to fail to free memory you have allocated. For example, this will do a "double free", trying to free a twice and failing to free b:
char *a = malloc(128*sizeof(char));
char *b = malloc(128*sizeof(char));
b = a;
free(a);
free(b); // will not free the pointer to the original allocated memory.
An example buffer overrun, which corrupts arbitrary memory follows. It is a buffer overrun because you do not know how long str is. If it is longer than 256 bytes, then it will write those bytes somewhere in memory, possible overwriting your code, possibly not.
void somefunc(char *str) {
char buff[256];
strcpy(buff, str);
}
Basically, in these languages, you have to manually request every bit of memory that is not a local variable known at compile time, and you have to manually release it when you don't need it anymore. The are libraries (so-called smart pointers) that can automate this process to some degree, but they are not applicable everywhere. Furthermore, there are absolutely no limits to how you can (try to) access memory via pointer arithmetics.
Manual memory management can lead to a number of bugs:
If you forget to release some memory, you have a memory leak
If you use more memory than you've requested for a given pointer, you have a buffer overrun.
If you release memory and keep using a "dangling pointer" to it, you have undefined behaviour (usually the program crashes)
If you miscalculate your pointer arithmetics, you have a crash, or corrupted data
And many of these problems are very hard to diagnose and debug.
I am planning to learn to program in C/C++
What exactly do you mean by that? Do you want to learn to program in C, or do you want to learn to program in C++? I would not recommend learning both languages at once.
From a user's perspective, memory management in C++ is a lot easier than in C, because most of it is encapsulated by classes, for example std::vector<T>. From a conceptual perspective, C's memory management is arguable a lot simpler. Basically, there's just malloc and free :)
I can honestly say that I have no "issues" with memory allocation when programming in C++. The last time I had a memory leak was over 10 years ago, and was due to blind stupidity on my part. If you write code using RAII, standard library containers and a small modicum of common sense, the problem really does not exist.
One of the common memory management problems in C and C++ is related to the lack of bounds checking on arrays. Unlike Java (for example), C and C++ do not check to make sure that the array index falls within the actual array bounds. Because of this, it is easy to accidentally overwrite memory. For example (C++):
char *a = new char[10];
a[12] = 'x';
There will be no compile or runtime error associated with the above code, except that your code will overwrite memory that shouldn't be.
The reason that this is commonly cited as something that is different in C/C++ is that many modern languages perform memory management and garbage collection. In C/C++ this is not the case (for better or for worse). You need to manually allocate and deallocate memory, and failing to do so correctly results in a memory leak that would not be possible in a language that performs memory management for you.
When new is used to gain a block of memory the size reserved by the operating system may be bigger than your request, but never smaller. Because of this and the fact that delete doesn't immediately return the memory to the operating system, when you inspect the whole memory that your program is using you may be made to believe that your application has serious memory leaks. So inspecting the number of bytes the whole program is using should not be used as a way of detecting memory errors. Only if the memory manager indicates a large and continuous growth of memory used should you suspect memory leaks.
It is obvious you have to release that memory which is no longer in use or not use in future, but you have to determine at the begining of the programme , the memory requirement is static or varied when it execute. If it dynamic you take enough memory for your program work that time may be your program consume extra memory.
so you have to release that memory which not in use and create that time when it is needed.
just like
struct student
{
char name[20];
int roll;
float marks;
}s[100];
Here I suppose 100 student in class. Student may be more than 100 or less 100. If more than 100 then your programme will lose information or less 100 then programme will run but waste of memory, it can be big.
so we are usually create a record dynamically at the time of execution.
just like
struct student *s;
s=(struct student *)malloc(sizeof(struct student));
scanf("%s %d %f",s->name,s->roll,s->marks);
if not in use then delete it form momery space.
free(s);
That is good manner for programming, if you not remove from memory then at one time it can full your memory stack and it can be hang.
One thing not mentioned so far is performance and why you want to manually manage memory.
Managing memory is hard to do accurately especially as a program becomes more complex(especially when you use threads and when the lifetime of pieces of memory becomes complex(ie when it gets hard when its hard to tell exactly when you don't need a piece of information)) even with powerful modern programing tools like valgrind.
So why would you want to manually manage memory,a few reasons:
--To understand how it works/to
--To implement garbage collection/automatic memory management you need to manually
--With some lower level things such as a kernel you need the flexibility manual control of memory can give.
--Most importantly if you do manual memory management right you can gain a large speedup/lower memory overhead(better performance), an associated problem with garbage collection(although its getting better as better garbage collectors such as the hotspot jvm one are written) is that you can't control memory management so it hard to do stuff with real time stuff(guaranteeing deadlines for certain objectives like car brakes and pacemakers, try special real time gc) and programs that interact with users might freeze up for a little bit or lag(this would suck for a game).
A lot of "Modern C++" (it has been said that C++ can be thought of as multiple languages depending on how you use it) as opposed to c with classes(or x and y C++ feature) use a compromise by frequently using simple optional gc/automatic memory management(note that optional gc can be worse at memory management then mandatory because when its mandatory its a simpler system) features and and some manual memory management. Depending on how you do this it can have some advantages and disadvantages of using gc and doing manual memory management. Optional GC is also available with some C libraries but its less common with c then c++.

Is it possible to use Boehm garbage collector only for the part of the program?

I've read article in LinuxJournal about Boehm-Demers-Weiser garbage collector library. I'm interesting to use it in my library instead of my own reference counting implementation.
I have only one question: is it possible to use gc only for my shared library and still use malloc/free in the main application? I'm not quite understand how gc checks the heap so I'm worrying about performance of gc in that case and possible side effects.
The example in the manual states:
It is usually best not to mix garbage-collected allocation with the system malloc-free. If you do, you need to be careful not to store pointers to the garbage-collected heap in memory allocated with the system malloc.
And more specifically for C++:
In the case of C++, you need to be especially careful not to store pointers to the garbage-collected heap in areas that are not traced by the collector. The collector includes some alternate interfaces to make that easier.
Looking at the source code in the manual you will see the garbage-collected memory is handled through specific calls, hence, the management is handled separately (either by the collector or manually). So as long your library handles its internals properly and doesn't expose collected memory, you should be fine. You don't know how other libraries manage their memory and you can use them as well, don't you? :)
I believe that yes, you can mix the two: however if you allocate an object with the normal allocator that holds a reference to an object you allocate with the garbage collecting one, then that reference will not be visible to the GC so that object may be prematurely deallocated.
Have a look at the GC_MALLOC_UNCOLLECTABLE function specification if you need the GC to take account of references in memory that shouldn't be collected.
In summary, yes, but here be dragons if you aren't careful!