Currently, I have all my objects managing their own memory, allocating with new
in their constructors typically, and using delete
in their destructors. This works for now, but the number of classes I have that use arbitrary amounts of memory is growing. The fact that new
is essentially a "request" also bothers me, since thes开发者_StackOverflow社区e objects have no code within them to handle being told "no", and I don't want to rely on Exception Handling if I do not need to.
Is it beneficial in terms of performance to completely shield all calls that allocate memory, to a single class that handles every memory allocation on the heap, probably allocating large chunks at a time and using placement new to deal out references?
Is the use of memory allocation in smaller classes a big enough concern to even bother with this?
Can I still use STL containers and force them to use the heap I provide?
Thank you in advance!
Can I still use STL containers and force them to use the heap I provide?
STL containers accept custom allocators:
http://en.wikipedia.org/wiki/Allocator_(C%2B%2B)#Custom_allocators
Here is a thread with links to samples:
Compelling examples of custom C++ allocators?
Is it beneficial in terms of performance ... ?
You can only find out by writing your application, coming up with a set of reproducible test scenarios, and running your code in a profiler. If you find the memory allocation to be a significant portion of the running time, then you might benefit from a better allocation strategy.
If you can break up your program to a feature level, and can come up with realistic scenarios for each case, you don't have to have your whole program working to do this. But remember that time spent optimizing is time that could be spent testing or coding new features :) Do what is necessary and no more...
Is the use of memory allocation in smaller classes a big enough concern to even bother with this?
Depending on your program, how sensitive you are to big allocation hitches, how often you allocate in loops, etc, it is possible. Profile :)
While developing your app, you can still be sensitive to allocations - create automatic storage (stack local) variables when you can, and allocate dynamically only when you must.
I'm not really sure I understand your problem here. That said, using STL containers in C++03 with your custom heap will be challenging, since allocators are considered stateless. Also, why don't you want to rely on exception handling? Are you aware that there is a no_throw version of new?
Edit: The no-throw version of new is invoked like this: new (std::nothrow) Type[size];
. If the allocation fails, it will return a null pointer (0
) instead of throwing std::bad_alloc
.
Can I still use STL containers and force them to use the heap I provide?
Yes, look up STL allocators.
Is it beneficial in terms of performance to completely shield all calls that allocate memory, to a single class that handles every memory allocation on the heap, probably allocating large chunks at a time and using placement new to deal out references?
That's basically what a good implementation of malloc
or new
does. I disrecommend doing it yourself unless the situation is very performance-critical and everything else has been optimized. Why? Because good and well-thought through memory management is very hard to even get bug-free, let alone working optimized.
Is the use of memory allocation in smaller classes a big enough concern to even bother with this?
It depends, if you're programming a coffee machine or gaming device with 16k of memory, perhaps, but on a regular desktop computer or laptop probably not. Also remember that the stack is very fast (allocation and access) while the heap is a lot worse on allocation and slightly (not so sure about that TBH) on usage so in day to day situations you want to prefer the stack.
You say you're calling new
in your constructors... Is that really necessary? I mean, instead of this...
class A{
std::vector<int>* v;
A( int vectorSize ){
v = new std::vector<int>( vectorSize, 0 );
}
~A(){
delete v;
}
};
...it's always preferrable to do this:
class A{
std::vector<int> v;
A( int vectorSize ):
v( vectorSize, 0 ){
}
};
This way you avoid using the heap. You should only use the heap when you have no other choice.
Asides from that, like the others said, writing your custom allocator is a very complex task and should only be done in a performance-critical scenario
I've done this before, and here's my experience:
- It can get very messy very quickly. Especially since you now take memory allocation into your hands and you have to deal with stuff like fragmentation and re-entrancy.
- However, I've seen performance boosts upwards of 20% due to being able to bypass the OS overheads.
For your last question, I think there is a way to make them use a custom allocator, but I've never done it before. I do most of my coding in C.
EDIT:
Based on your comment, here's an update. You don't really have to deal with building an allocator. You can probably get away with just pointing all memory allocations to your custom class. Then your custom class will call malloc()
or new
and catch whatever NULL or exception is returned.
(Though it will take some work replacing every single new
with your own malloc()
.)
精彩评论