【问题标题】:Memory size of classes in Objective-CObjective-C 中类的内存大小
【发布时间】:2012-01-26 02:37:00
【问题描述】:

我有兴趣知道内存的大小,分配一些 Objective-C 对象。

例如:

[NSString stringWithString:@"2"] 是否大于[NSNumber numberWithInt:2]

[NSNumber numberWithInt:2]int num=2 大多少?

Apple 有没有关于这个问题的文档?我认为这些信息对于内存优化非常重要。

【问题讨论】:

  • 欢迎来到 Stack Overflow。请在您的问题的格式上付出一些努力,例如使用代码格式和段落以获得更好的可读性。

标签: iphone ios memory-management


【解决方案1】:

据我所知,没有确切的文档。 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 需要的内存大约是ints 的五倍。我进一步估计,以NSString 表示的相同数字所占用的内存大约是int 的10 倍。

还要注意,分配 Objective-C 对象比定义 int 类型的局部变量要慢很多。但是,您还应该记住,这通常无关紧要,过早的优化是万恶之源

【讨论】:

    【解决方案2】:

    没有NSStringNSNumber 这样的东西,它们的逻辑实际上是在多个不同的类中实现的,每个类或多或少都有自己的内存占用。所以不可能说一个类在运行前有多少权重(但是你可以向 ObjC 运行时询问这个)。 这就是说,另一件事是 [NSNumber numberWithInt:2] 很可能会返回一个 NSNumber 的单例实例(当然,每个 12 以内的整数都会被缓存),所以你并没有真正在你的内存占用中添加任何东西。

    除此之外,去优化你的记忆是错误的方式!如果一个对象的权重比另一个多 64 个字节,那又如何呢?即使在 iPhone 上,64 字节也算不了什么!你最终会遇到更大的内存问题,你可以实际优化,例如。通过延迟加载你的东西或其他任何东西。但是这些问题是在使用 Instruments 进行测试时发现的,而不是在您编写代码时发现的! (您会惊讶地发现,即使在测试运行之前进行的简单“优化”往往没有效果,甚至对性能的影响更差!)

    【讨论】:

    • +1:优化应用程序的内存占用(通常)没用。除非你遇到这样的事情:cocoawithlove.com/2010/08/alternative-objective-c-object.html
    • Nit:你说“很可能会返回 NSNumber 的单例实例”。但这不是单例。单例是整个类中的唯一实例。您不能实例化多个单例。所以,返回的是一个 unique 对象,但它不是一个单例。
    【解决方案3】:

    在 NSNumber 和 NSString 的情况下

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

    在我的 Mac(有 64 位指针)上给出 8 和 8。

    文档在这里: http://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418-CH1g-SW38

    【讨论】:

      【解决方案4】:

      看看Instruments。这些工具应该能够回答您的问题。

      【讨论】:

      • 我知道分配和泄漏工具,但我认为在运行时测量对象大小 - 是了解类型大小信息的非常奇怪的方式。我确定这一定在文档中的某个地方。
      • 这也是我想到的第一件事,但我开始使用 Instruments,当可执行文件启动时(一个简单的 CLU)cocoa 也会自动创建其他对象。所以不可能知道你创建的是哪个对象。
      猜你喜欢
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 2011-06-26
      • 2011-06-28
      • 1970-01-01
      相关资源
      最近更新 更多