我很想知道内存的大小,分配一些Objective-C对象。
例如:
[NSString stringWithString:@"2"]
是否大于[NSNumber numberWithInt:2]
?
[NSNumber numberWithInt:2]
比int num=2
大多少?
Apple是否有关于此问题的文档?我认为这些信息对于内存优化非常重要。
答案 0 :(得分:14)
据我所知,确切的文档不可用。 NSString和(IIRC)NSNumber实现为类集群,即当您要求新对象时,可能实际上获得了一些未记录的子类的对象。
这也意味着当程序在不同的操作系统版本上运行时,事情可能会在没有警告的情况下发生变化,因此不要依赖于确切的数字。
现在,让我们粗略估计一下。所有当前Apple平台上的整数都是4个字节。 指针在iOS上是4个字节。
对象在堆上分配;在最低级别,堆分配由malloc
完成。
我将假设iOS的malloc实现源自Mac OS上使用的实现 - 请在此处查看一些详细信息:http://cocoawithlove.com/2010/05/look-at-how-malloc-works-on-mac.html
最重要的一点是小对象的分配量是16个字节,即小对象将占用16个字节的倍数。
每个Objective-C对象都包含一个指向其类的指针。
所以,对于一个包含int的NSNumber,我估计你的指针有4个字节,加上16个字节用于对象(由一个4字节的类指针组成 - 我想 - 一个四字节的int,加上8个字节浪费的空间)。
对于NSString,不同情况下有不同的具体子类。字符串文字@"2"
将指向静态分配的字符串文字对象,在运行时创建的字符串可能具有不同的表示形式。
一般来说,我猜4个字节(你的指针)+ 16个字节(NSString对象)+字符数* 2(sizeof(unichar))四舍五入到16的倍数。
总结一下,我估计 NSNumbers
需要的内存大约是int
的五倍。我进一步估计,表示为NSString
的相同数字的内存大约是int
的10倍。
另请注意,分配Objective-C对象比定义int类型的局部变量要快很多。但是,您还应该记住,通常无关紧要,并且过早优化是所有邪恶的根源。
答案 1 :(得分:4)
没有NSString
或NSNumber
这样的东西,它们的逻辑实际上是在多个不同的类中实现的,每个类都有或多或少的自己的内存占用。所以不可能在运行之前说出一个类的权重(但是你可以向ObjC运行时询问这个)。
这就是说,另一件事是[NSNumber numberWithInt:2]
很可能会返回NSNumber
的单例实例(每个高达12的整数都被缓存),所以你并没有真正为你的内存占用增加一些东西。 / p>
除了这一切之外,优化记忆的方法是错误的!如果一个对象比另一个重64个字节,那又怎样? 64字节都没有,即使在iPhone上也是如此!你最终会遇到更大的内存问题,你可以实际优化,例如。通过懒惰加载你的东西或其他什么。但是这些问题是在使用Instruments进行测试时发现的,而在编写代码时却没有! (你会惊讶地发现,即使在测试运行之前,一个简单的“优化”也没有效果,甚至对性能影响更小!)
答案 2 :(得分:2)
对于NSNumber和NSString
NSLog(@"size was %ld", class_getInstanceSize([NSNumber class]));
NSLog(@"size was %ld", class_getInstanceSize([NSString class]));
在我的Mac上有8位和8位(有64位指针)。
答案 3 :(得分:1)
看看Instruments。这些工具应该能够回答您的问题。