Back to once approach
- 1 Overview
- 2 Introduction
- 3 Explanation in Example
- 4 Search Routes in Memory Analyzer
In this article, I introduce a way in Eiffel to help fixing memory leaks. I call it Back to Once approach.
What is Back to Once? The general idea is that we take a memory short in which one provide a start object, in principle part of leaking objects, to Memory Analyzer that returns routes from the given object to once objects. With these routes one can find out bad links and corresponding code more easily. This approach is based on the point that one or more bad links MUST exist in found routes as long as the given start object is part of leaks.
Explanation in Example
Example system code
We use the following code to construct an example system where A-L are classes with simple attributes and set_X routines.
make_relation is local a: A b: B c: C e: E f: F g: G h: H i: I j: J l: L do create a create b create c create e create f create g create h create i create j create l a.set_e (e) a.set_j (j) b.set_a (a) c.set_b (b) e.set_f (f) e.set_l (l) f.set_g (g) f.set_i (i) g.set_h (h) h.set_a (a) i.set_l (l) j.set_k (k) l.set_c (c) array_list.extend (h) end array_list: ARRAYED_LIST [H] is once create Result.make (2) end k: K is once create Result end
Object relations in example system
With previous code, the object relations in the memory should like this:
Once is an object of ARRAYED_LIST [H], K is an once object and one may have guessed, M is a object of SPECIAL [M].
Fixing memory leaks in sample system
The first step is to choose an object as a start object
As I said, a start object should be an object of the leaks. Otherwise, routes found are valid routes and useless for the leak fixing. How to identify an object part of leaks? Programmers can come up with various approaches. Digging memory leaks of EiffelStudio mentions one of them.
Now we suppose B is of leaks.
Finding routes of Back to Once for B
With Memory Analyzer, we get the route: Route1: ARRAYED_LIST [H] -> SPECIAL [H] -> H -> A -> E -> F -> I -> L -> C -> B
Of course, one may get different one, but it helps us fix leaks in the same way.
The route is demonstrated in the following diagram with blue arrows.
Now we have a Back to Once route in hand, how does it help?
We know that there is at least a bad link in this route, how to decide a black sheep, maybe more? It depends. Take a look at the following diagram, there are four regions R1-R4. One need to decide objects in this route a leak or not, in other words, one need to find the edge of leaks and non-leaks. Obviously, in this example, not all object in R3 are possibly leaks, because we know that area: SPECIAL [X] is one attribute of ARRAYED_LIST. We can do little to cut this link out of the base library. The rest R1, R2 and R3 are all possible invalid regions, namely leaks. Respectively links M->H, H->A and A-E are possible edges need to cut. The decision of edge is made by the programmer who knows the logic in his system. If A is part of valid object and E is not, the programmer knows that A->E should be cut programmatically in his system. Then G, F, E, B, I, L and C will be garbage collected. Programmers can have more regions and decide which link is of the edge.
Fixing leaks in all routes
Once a leak is fixed, one should relaunch Memory Analyzer to find the next route and fix it in the same way until all leaks by one operation are fixed.
Search Routes in Memory Analyzer
- In any situation one expect, click Refresh information button in the tool bar.
- Switch to Object Grid panel. Expand object nodes and choose a starting object by the check box in the third column.
- Enable statics collection in the tool bar.
- Click Refresh information button in the tool bar again. (Be patient, this will take some minutes to finish dependingly, seriously. It varies depending on machines, how big the system is and how the system was compiled.)
- Switch to Search Route panel. And now one can click Search Next Route button on the top. The results are listed leading by once objects found and trailing by the starting object.