Archived Forum Post

Index of archived forum posts

Question:

memory leak with CkoImap (iOS)?

Jun 28 '16 at 19:46

I have been working with retrieving emails and attachments and can not get around a possible memory leak. I tested with this example code and get the same result: https://www.example-code.com/swift/imap_downloadAttachment.asp

The mailbox has over 11,000 email, but the problem is as it loops over the messageSet, the memory keeps climbing. I have tried using smaller MessageSets and get the same result. I am not saving any attachments nor loading into memory.

This can be duplicated by running the sample code from the link above on an IMAP email account with a lot of emails. iOS eventually will terminate the app.

Anybody experienced this?

Thanks, Edward


Accepted Answer

Hi Edward,

I think I understand what's happening. First, I'll repeat what I said earlier for the benefit of others reading this response: If a memory leak truly exists in Chilkat, then it can be located in one of two places:

1) It can be in the outer-layer of the API. For all programming languages supported by Chilkat, this layer is not hand-written but is generated. The outer layer handles the transition from the programming language (Swift/Objective-C in this case) to the inner C++ implementation. Methods that return a newly created Chilkat object, such as imap.Search, imap.FetchHeaders, or bundle.GetEmail, all do so in the exact same way. If a memory leak actually exists in the outer-layer code, then the same memory leak would exist for all Chilkat objects performing the similar task (such as returning an object). This is unlikely go to unnoticed, and therefore I don't suspect it's a likely source of the error.

2) The other possible location for a memory leak is in the inner C++ implementation. Checking for this can be done in C++ itself, because the underlying C++ code is 99% identical across all operating systems. (Chilkat uses very few #ifdef's) I tested this example using C++ where I can detect even the slightest memory leak, and found no problems.

So.. I don't think there's an actual memory leak, but I think I understand why memory is not getting released. (A memory leak is if the memory never gets released. I think this is a case where the memory would eventually get released, but the code is written such that it never gets to the point of releasing the accumulated objects.)

First, see this: http://stackoverflow.com/questions/5192308/objective-c-autorelease-memory-management It's relevant because the objects returned by Chilkat are autoreleased objects:

An autoreleased object is added to an autorelease pool.

Objects in the autorelease pool are released at the end of an iteration of the main runloop (or sooner if you are managing your own autorelease pool and/or if you call drain).

When you call a method that returns an autoreleased object, it is pretty much guaranteed to stay valid until at least the end of the scope that it was called in.

If you want to ensure that it stays alive longer then you should retain it, remembering to release it again when you're finished with it.

So.. what is the end of a run loop??? See this: http://stackoverflow.com/questions/5766839/end-of-run-loop-autorelease-pool-recovery

I suspect what's happening is that you run out of memory before getting to the end of the run loop -- which is the point at which the autorelease objects can be recovered (released).


Answer

Great!

I enclosed the looping in:
autoreleasepool{

} Now all is well.

Thanks!