Skip to content

v1.4 memory leaks #36

Open
shuge opened this Issue Jul 8, 2011 · 16 comments
@shuge
shuge commented Jul 8, 2011

test environment XCode4

line 2318

- (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error
{
  if(parseState == NULL) { [NSException raise:NSInternalInconsistencyException format:@"parseState is NULL."];          }
  if(string     == NULL) { [NSException raise:NSInvalidArgumentException       format:@"The string argument is NULL."]; }

  return(_JKParseUTF8String(parseState, NO, string, (size_t)length, error));
}
@johnezang johnezang was assigned Sep 23, 2011
@johnezang
Owner

There isn't enough information in the bug report to determine what the problem is. Specifically:

  • What was leaked?
  • The line referenced does not do any allocation. In fact, the method does no allocations, so this method can't "leak" anything.

Since the leak tools (typically) show you the place in the code in which the allocation was made, it is entirely possible to have objects created by JSONKit turn up as leaked objects, but are not leaked due to a bug in JSONKit. For example, if you sending an object returned by JSONKit a retain message, without a balancing release, and there are no pointers to the objects that are reachable from the set of "strong roots", then that object will show up as a leak in the tools. The tools will report at what line in the source the object was allocated, but this does not tell you at what point the object was actually leaked.

@j3rm
j3rm commented Nov 23, 2011

I show the same thing. Look in

static JKDictionary *_JKDictionaryCreate(id *keys, NSUInteger *keyHashes, id *objects, NSUInteger count, BOOL mutableCollection)

The line is

if(JK_EXPECT_F((dictionary->entry = (JKHashTableEntry *)calloc(1UL, sizeof(JKHashTableEntry) * dictionary->capacity)) == NULL)) { [dictionary autorelease]; return(NULL); }

I show 99% next to the line. I have screen shots that follow this memory leak

I am downloading a TON of data and this memory error show very quickly.
My code is as you suggested: I init the decoder when my class is loaded, then I call the objectWithData, over and over and when my class is dealloc, I release the decoder.
I am not retaining or copying the returned json.
I even wrapped the calls in a NSAutoreleasePool and release and it did not resolve the issue.

@j3rm
j3rm commented Dec 4, 2011

Any update on this?

@j3rm
j3rm commented Dec 6, 2011

I' d really like to see this fixed. Sooner than later. Any chance a Paid support Session would get this resolved?

@ohhorob
ohhorob commented Dec 7, 2011

You should consider using heapshot analysis to resolve your memory issues (http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/).

While it's possible you've found a bug in JSONKit, it's far more likely that your codes' object management strategy is causing the leaks.

@j3rm
j3rm commented Dec 7, 2011

if its my code id be so happy, i can fix that. ill look into it and report back, thanks for the tip.

@j3rm
j3rm commented Dec 8, 2011

I have looked into this article and i tried to employ the methods but all of the alloc and retains appear to be happening with in the jsonkit libraries, and everything brings me back to the same line of code.

My code that calls jsonKit is wrapped around a dedicated NSAutorelease pool and I am not copying, retaining etc anything I get form the jsonKit decoder. Would love to see this fixed, it causes my app to crash after about 20-30 mins of syncing. I honestly would pay to have this resolved. If @ohhorob you think this is my code, and would be willing to look at this with me, I would be happy to reimburse you for your time.

@sbooth
sbooth commented Dec 8, 2011

Can you concoct a simple example that illustrates the issue?

@MikeWeller

I suggest you use the Allocations tool in Instruments with the "Record reference counts" option enabled. It will tell you exactly where the objects are being alloc'd, retained and released.

I'm sorry to have to side against you, but I've used JSONKit a lot myself without coming across memory leaks, so I have to say it sounds like a problem in your own code. We could all be wrong though :)

@leearmstrong

I think I get this issue too although not sure 100%.

The code I have is

__block __typeof__(self) _self = self;

PINKConnectionCompletionBlock complete = ^(PINKConnection *connection, NSError *error) {
    if (error) {
        NSLog(@"Failed to get data");
    } else {            
        JSONDecoder *decoder = [JSONDecoder decoder];
        _self.mainDictionary = [decoder objectWithData:[_self.download downloadData]];
        [_self translateToObjectFromDict:_self.mainDictionary];
    }
    _self.download = nil;
};

self.download = [PINKConnection connectionWithURL:downloadURL
                                    progressBlock:nil
                                  completionBlock:complete];
[self.download start];

And the leak is shown as

http://lesmond.net/images/JSONLeak.png

@johnezang
Owner

@leeus,

You assigned the object that JSONKit creates to self.mainDictionary using the following line:

    _self.mainDictionary = [decoder objectWithData:[_self.download downloadData]];

... are you sure that in _self's -dealloc method you are properly releasing mainDictionary? I suspect you forgot to [_mainDictionary release];, or something along those lines (where _mainDictionary directly references the ivar for the mainDictionary property).

@leearmstrong
@johnezang
Owner

@j3rm,

I'm sorry, but there really is no update. You have provided very little information, other than

  • The line in JSONKit that allocates memory for the returned object.
  • You are getting "a ton" of leaks.

At this point, JSONKit has been used extensively by a great many people and many apps. This does not mean it is bug free or does not have memory leaks, but more than likely the problem is not with JSONKit.

IMHO, the few clues that you have provided strongly suggest that you have not correctly balanced your retains and releases. As a suggestion, you could try adding an extra autorelease immediately to the object that JSONKit returns along with enabling zombies. If the extra autorelease magically fixes things, then the problem is definitely on your end. However, because you are forcibly causing an intentional over-release of the object, it's difficult to say exactly what will happen. With zombies enabled, you'll get a message on the console if anything attempts to send a message to the object after it has been dealloced, which will probably give you a clue as to what and where you over-retained the returned object.

@johnezang
Owner

@leeus,

From your description, it sounds like you probably have the @property declaration set to assign, when it really should be retain.

@leearmstrong
@j3rm
j3rm commented Dec 15, 2011

@johnezang, I believe my problem to be resolved. its not with JsonKit.
Thanks for the reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.