Google Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: Phone Interview
Run your application within a profiler such as `valgrind`. A profiler can provide observations about the amount of memory used, and, more importantly, about possible memory leaks in your program.
1) Determine input data set that achieves 100% code coverage.
If profiling is possible:
2) Call instrumented API with this data set
3) Observe leak reports
If profiling is not possible:
2) Call API repeatedly (i.e. in a loop) with this data set
3) Measure memory usage of process over time
If memory measurements are not possible:
2) Call API repeatedly in a loop for extended periods of time
3) Run other applications on host system to evaluate impact of API
As the author of the API, we ensure no memory leak by
1. making object ownerships clear.
2. protecting heap allocation with smart pointers.
3. output arguments should be provided from caller or use sharedptr.
As a user of the API, we can do some test.
1. use tools with memory leak detection, i.e. valgrind.
2. limit the heap memory of the program and simply try to amplify possible memory leak by repeatedbly calling the API.
Write some wrapper function for malloc/free etc dynamic memory allocation API, and add some statistics based on the time-stamp and thread ID in there. Each time before call the API, get a snapshot of the current memory usage of that thread, and after call the API, check its current thread related memory usage is the same of the snapshot taken before the API call, fatal if they are different unless you know that the API itself will need to allocate the memory.
Conceptually the idea is good. But wondering if there is a way to get a snapshot of the current memory usage of a thread from application level without digging into the operating system level issues?
This doesn't "make sure" the API can't leak memory. The question seems to imply it should never leak by construction. If that's the case, only Varun's answer is applicable: you can't leak memory if you simply don't allocate yourself any in the first place.
For the question itself, it is asking people to make sure that an API does not leak memory. If the "people" are API designer, you gonna have a list of strategy for this, as listed above. But all in all, the word is "not allocation memory, or free it after allocation before exiting", it is kind of good wish, but not a systematic method to make sure of this. So finally the people are the API tester, whatever he is unit tester or real user, you need a way to check it in black box style.
For the question arised by Romonov, how to provide a snapshot of a thread application level without digging into the operating system level. Well, there are two cases, one is that the memory leak is caused by the API's call of malloc, another issue is that the memory leak is caused by some functions (beside the direct memory allocation API) called by the API logic, but unfortunately the logic forget the side effect of this API and does not follow some predefined protocol to free it, or what's more, the function the API calls has memory leak, the latter case it is difficult to handle. We may really need to replace some libc implementation of memory allocation, which will call the raw exception based system call, and let the gcc to use the libc when linking the test application.
Inside the API use a local variable. Increment it when there is allocation and decrement it when some location is freed.This way ensures individual API not creating Mem leak.. But some times freeing can happen in some other APIs. In those cases increment/decrement should not be done. But to track them an ID of the API can be appended to malloc() structure.
A good API design should involve the following:
1. No state management. Push all state management to client code.
2. Idempotent. Same input will always provide the same output.
3. No Transaction management. Again, push it to client code.
4. Service oriented - meaning, provide a specific elemental service
When you apply all these design principles, your API code will automatically become lean. From that perspective, everything you will do becomes 'disposable' - all objects and primitive variables that you will use to service a certain request will become disposable.
Then comes the bloody internals. Ensure no loitering, reset your collections references to null etc.
But I believe that a good overall design principle are must for eliminating conditions for memory leaks.
Well I guess there are couple of ways we can approach this
- hprem991 March 20, 20131> Design API such that it only Process the functionality and no memory allocation within it.
2> Use the Smart pointer concept for every pointer usage within the API.
3> Can make API's so that for every allocation there must be the deallocation called in. for every condition.