7

I'm interested in knowing the size of memory, allocating some Objective-C objects.

For example :

Is [NSString stringWithString:@"2"] bigger than [NSNumber numberWithInt:2] or not?

And how much bigger is [NSNumber numberWithInt:2] than int num=2 ?

Is there some documentation from Apple about this question? I think this information is very important for memory optimisation.

Todd Lehman
  • 2,880
  • 1
  • 26
  • 32
Padavan
  • 1,056
  • 1
  • 11
  • 32
  • 1
    Welcome to Stack Overflow. Please put some effort in the format of your question, e.g. use code formatting and paragraphs for better readability. – tobiasbayer Dec 22 '11 at 12:58

4 Answers4

14

Exact documentation is not available, to the best of my knowledge. NSString and (IIRC) NSNumber are implemented as class clusters, i.e. when you ask for a new object, you might actually get an object of some undocumented subclass.

It also means that things may change without warning when your program runs on a different OS version, so don't rely on exact numbers.

Now, let's try a rough estimate. Integers are 4 bytes on all current Apple platforms. Pointers are 4 bytes on iOS.

Objects are allocated on the heap; at the lowest level, heap allocation is done by malloc. I will assume that iOS's malloc implementation is derived from the one used on Mac OS - Look here for some details: http://cocoawithlove.com/2010/05/look-at-how-malloc-works-on-mac.html

The most important point is that the allocation quantum for small objects is 16 bytes, i.e. small objects will use up a multiple of 16 bytes.

Every Objective-C object contains a pointer to its class.

So, for a NSNumber containing an int I'd estimate 4 bytes for your pointer, plus 16 bytes for the object (consisting of a 4-byte class pointer and - I guess - a four-byte int, plus 8 bytes of wasted space).

For a NSString, there are different concrete subclasses for different situations. A string literal @"2" will point to a statically allocated string literal object, a string created at runtime will probably have a different representation. In general, I'd guess 4 bytes (your pointer) + 16 bytes (the NSString object) + number of characters * 2 (sizeof(unichar)) rounded up to multiples of 16.

To summarize, I estimate that NSNumbers need about five times more memory than ints. I further estimate that the same number represented as an NSString takes about 10 times more more memory than an int.

Also note that allocating objective-C objects is a lot slower than defining a local variable of type int. However, you should also remember that it will often not matter and that premature optimization is the root of all evil.

wolfgang
  • 4,883
  • 22
  • 27
4

There isn't such a thing as a NSString or a NSNumber, the logic of them is actually implemented in multiple different classes, each of them having more or less their own memory footprint. So its impossible to say how much a class weights before runtime (you can however ask the ObjC runtime about this). This said, another thing is that [NSNumber numberWithInt:2] will most likely return a singleton instance of NSNumber (afair every integer up to 12 is cached), so you don't really add something to your memory footprint.

And beside everything of this, going to way to optimize your memory is the wrong way! If an object weights 64 bytes more than the other, so what? 64 bytes are nothing, even on an iPhone! You will end up with bigger memory problems where you can actually optimize, eg. by lazy loading your stuff or whatever. But these problems are found during testing with Instruments and not ahead when you write your code! (You would be surprised how often a simple "optimization" made even before test running has either no effect or even has a worse performance impact!)

JustSid
  • 25,168
  • 7
  • 79
  • 97
  • +1: it's (normally) useless to optimize the memory footprint of an application. Unless you're running into something like this: http://cocoawithlove.com/2010/08/alternative-objective-c-object.html – v1Axvw Dec 22 '11 at 13:27
  • Nit: You say "will most likely return a singleton instance of `NSNumber`." But that's not what a singleton is. A singleton is the only instance *in the entire class*. You can't have multiple singletons instantiated. So, what is returned is a *unique* object, but it is not a singleton. – Todd Lehman Mar 11 '16 at 00:05
2

In the case of NSNumber and NSString

NSLog(@"size was %ld", class_getInstanceSize([NSNumber class]));
NSLog(@"size was %ld", class_getInstanceSize([NSString class]));

gives 8 and 8 on my Mac (which has 64 bit pointers).

Documentation is here: http://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418-CH1g-SW38

sdsykes
  • 1,256
  • 12
  • 15
1

Have a look at Instruments. These tools should be able to answer your questions.

tobiasbayer
  • 10,269
  • 4
  • 46
  • 64
  • I know about Allocations and Leaks tools but I think that measuring objects size in runtime - is very strange way to know information about types sizes. I'm sure that must be somewhere in documentation. – Padavan Dec 22 '11 at 13:02
  • This was the first thing that came to mind here too, but I started to play around with Instruments, and when the executable launches (a simple CLU) cocoa automatically creates other objects too. So it's impossible to know which object is the one you've created. – v1Axvw Dec 22 '11 at 13:19