The reference code extracts the relevant code. In the csdn Resource Station of Xiaosheng, download the code at. The link is as follows. Http://download.csdn.net/detail/noslopforever/4568056download please use this resource connection. The tracer variant of tracer is slightly changed to record more information. For example, if you do not need to use Hash, you can directly use a list to record it. If you do not use free, the list will not be deleted from the hash. The list will only become larger and larger, record information such as the allocation time, destruction time, allocation size, thread, and so on. In this way, the memory of the entire application can be monitored. U3 uses dbghelp trace to record all the distributions of the current application, for a period of time, or even the entire application life cycle. In this way, we can provide more information about memory allocation, know when the memory allocation calls are too concentrated, and when the memory destruction calls are too concentrated, still, allocation and destruction are smoothly executed and developed. However, every time new information is added, the tracer will become slower. Advantages and disadvantages of file line tracer and dbghelp Tracer
First, in terms of performance, the information required by file line tracer comes from the compilation phase. There is no new call overhead in addition to the program stack and hash during runtime, while dbghelp information comes from runtime, the overhead is naturally much larger than file ln tracer.
Then, define new is required for file line tracer, which introduces some minor troubles. dbghelp tracer does not need this. Expand after define new.
Then, file line tracer only knows the file and row number where the current statement for memory allocation is located. However, dbghelp can also give the current call stack for memory allocation, it is more conducive to quickly locating the wrong allocation ".
The define new of file line tracer and the problems arising therefrom
The biggest problem with define new is that you need to ensure that the # define new debug_new macro is called before new.
When the header file contains a chaotic relationship, this is quite uncomfortable. If there is a pre-compilation header, you can add this sentence to the first line of the pre-compilation header. However, when there is no pre-compiled header, you need to maintain its correctness.
Otherwise, in case. h In New ,. delete in CPP (or the opposite), and define new occurs again in this. h later, it is very easy to misjudge the situation, a new is clearly deleted, but not recorded, so a false positive reported Memory leakage, or a deleted object is not newly deleted ......
The sequence of header files is really a permanent pain in C ++ ......
Tracer optimization cookie Optimization
No matter which tracer, some code overhead is added.
If the memory splitter is also written by itself, it is convenient to note that some small cookies can be split before memory allocation, and the required information is recorded in these small cookies. When you need this information, you only need to forward several bytes to obtain the cookie, which has the highest performance, but introduces two problems:
I. The full set of memory allocation should be done by myself. Mature third-party allocation such as dlmalloc and tlmalloc cannot be used, which is why independent tracer is used in my example code.
2. Check that the memory currently accessed is allocated by the Allocator. Once new and delete are not paired, this issue will spring up. A bad solution, but in most cases, is to record a magic number in the cookie. when accessing the cookie, you must first determine whether the magic number can be matched. After all, in most cases, the data in the memory is very unlikely to match the magic number. However, this problem is hard to prevent. This problem may become more and more prominent when you provide not a full set of solutions, but a small module that will be referenced by other people at the code level rather than the binary level.
To avoid the hash overhead of multi-process optimization, another method is to use another thread to send trace information to other processes for processing. Because messages can be queued and processed when the program is idle and exited, the overhead of running the program will be reduced. The specific method can be file writing, TCP transmission to other servers, or shared memory writing, depending on your own wishes and test results. Memory occupied by optimization
If we change the trace as described in the "Variant" section to "full interception" and never destroy it, then the problem we will face next is that once the allocation is increased, this memory usage is rising.
At this time, there is also a scheme to change tracer to not be processed by this process, but to send messages to other applications through TCP connections for interception and processing. However, for dbghelper, the message sent must include the full text of the call stack. Otherwise, it will be much more troublesome for another application to obtain only the stack tag. Fortunately, the sending thread can be established in another thread, and the full-text information of each call stack can be cached once after it is obtained. The total number of full-text information of the Call Stack is less than the allocation number, right?
Tracer cross-module call
After tracer is deployed across modules, it becomes a headache.
If all the modules are maintained by yourself, you can ensure that your tracer can be used fairly in each module without any problems.
However, if you are creating a release, relatively refined, and with a single function, tracer should be very careful.
First, you may not want to enable the tracer function of this module. Therefore, you need to provide a dedicated memleak debug version.
Then, if you use tracer, ensure that the memory generated by tracer new is monitored by tracer for Delete. Here, you need to maintain the principle of "delete this module new this module, but the principle is that it is easy to do. You got a shot, right?
Then, if you do not want to use tracer, or do not want to use tracer, you need to remove tracer from the include file of the distribution version. the corresponding use in H requires macro shielding. This is what everyone should do, and the right should be nonsense.
Finally, if you want to use your tracer, believe me, this is just the beginning of a nightmare ...... You will never know how users use your provided libraries and interfaces ...... So the only thing they can do is to make them have no choice.
The cross-module feature is a very confusing feature. If you have a fully controllable project, we recommend that you do not go too far on this road. After all, it is the best thing to adapt to. What do you mean?