释放后 CATextLayer 内存残留
我最近刚刚开始 iPhone 开发,并且仍在摸索中。在测试各种 CALayer 和 CATextLayer 行为时,我偶然发现了一些有趣的东西。
我创建了一个 iPhone 测试应用程序,它的视图中只有 2 个 UIButton。其中一个调用“allocateAutoReleasedLayers”函数,另一个调用“deallocateAutoReleasedLayers”函数。以下代码片段代表函数体。
-(IBAction)allocateAutoReleasedLayers:(id)sender
{
for ( int i = 0; i < 500; ++i )
{
CALayer * layer = [ CALayer layer ];
[ master addSublayer: layer ];
}
}
-(IBAction)deallocateAutoReleasedLayers:(id)sender
{
master.sublayers = nil;
}
现在,测试的目的是看看 iOS 如何处理图层自动释放。当使用“分配”分析器运行时,该应用程序占用 646.452 字节的内存。在我点击“分配”按钮后,内存使用量上升到 719.228 字节来托管创建的所有 500 个空层,这是可以的,因为当我点击“解除分配”按钮时,已用内存回落到 656.732 字节(我猜想分配之前和释放之后使用的内存不匹配是iOS内部内存管理的结果。
当我更改“分配”过程的部分以创建 CATextLayers 而不是 CALayers 时,有趣的部分发生了。
-(IBAction)allocateAutoReleasedLayers:(id)sender
{
for ( int i = 0; i < 500; ++i )
{
NSString * layerString = [ [NSString alloc ] initWithFormat: @"1231" ];
CATextLayer * textLayer = [ CATextLayer layer ];
[ textLayer setString: layerString ];
[ textLayer setFrame: CGRectMake( 0, 0, 100, 200) ];
[ textLayer setFont: @"Helvetica-Bold" ];
[ textLayer setFontSize: 20 ];
[ master addSublayer: textLayer ];
[ layerString release ];
}
}
该应用程序在分配之前通常使用 651.868 字节,然后上升到使用的 2.13MB(我猜 CATextLayers 的内存使用量相当大),在释放后,内存回落到 950.372 字节。
现在,我的问题如下:在处理 CATextLayers 时,导致分配之前和释放之后 300kB 差异的原因是什么。我想我对 iOS 管理内存的方式的误解可能是原因,但我使用了与创建 CALayer 时使用的完全相同的方法来创建 CATextLayer。
预先致谢并致以诚挚的问候!
I've just recently gotten into iPhone development and i'm still in the process of figuring stuff out. While testing various CALayer and CATextLayer behavior, i've stumbled upon something interesting.
I've created an iPhone test app which only has 2 UIButtons in a view. One of them calls 'allocateAutoReleasedLayers' function and the other 'deallocateAutoReleasedLayers' respectively. The following code snippets represent function bodies.
-(IBAction)allocateAutoReleasedLayers:(id)sender
{
for ( int i = 0; i < 500; ++i )
{
CALayer * layer = [ CALayer layer ];
[ master addSublayer: layer ];
}
}
-(IBAction)deallocateAutoReleasedLayers:(id)sender
{
master.sublayers = nil;
}
Now, the purpose of the test was to see how iOS handles layer autoreleasing. When run with the 'Allocations' analyzer the app takes up 646.452 bytes of memory. After I hit the 'allocation' button, the memory usage goes up to the 719.228 bytes to host all of the 500 empty layers created, which is ok since when I hit the 'deallocate' button, the used memory falls back to 656.732 bytes (i guess that the mismatch in the memory used before allocation and after deallocation is a result of iOS' internal memory management).
The interesting part happens when i change the part of the 'allocation' procedure to create CATextLayers instead of the CALayers.
-(IBAction)allocateAutoReleasedLayers:(id)sender
{
for ( int i = 0; i < 500; ++i )
{
NSString * layerString = [ [NSString alloc ] initWithFormat: @"1231" ];
CATextLayer * textLayer = [ CATextLayer layer ];
[ textLayer setString: layerString ];
[ textLayer setFrame: CGRectMake( 0, 0, 100, 200) ];
[ textLayer setFont: @"Helvetica-Bold" ];
[ textLayer setFontSize: 20 ];
[ master addSublayer: textLayer ];
[ layerString release ];
}
}
The app starts with the usual 651.868 bytes usage before the allocation and rises up to the 2.13MB used (i guess CATextLayers are pretty heavy on memory usage), and upon deallocation the memory falls back to the 950.372 bytes.
Now, my question is the following: what happened to cause those 300kB difference before allocation and after deallocation when dealing with CATextLayers. I guess that my misunderstanding of the way iOS manages memory might be the cause but I've used the exact same way of creating CATextLayer as I've used in CALayer creation.
Thanks in advance and best regards!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经在模拟器上运行了你的代码,但我看不到这种行为。以下是我执行的步骤:
1) 在“分配”工具下运行应用程序。
2) 等待其完全启动。
3) 标记堆->堆(0)
4) a) 使用
allocateAutoReleasedLayers:
分配 CATextLayer 实例b) 使用
deallocateAutoReleasedLayers:
取消分配c) 标记堆-> Heap(1)
操作4给我们一个测试模式(分配-释放-标记堆),所以
5) ADM(2) ->堆(2)
6) ADM(3)→堆(3)
7) ADM(4)→→堆(4)
...
执行 ADM(n) 时,Heap(n) 和 Heap(n-1) 之间的差异约为 2K,而执行 ADM(n+1) 时,Heap(n) 和 Heap(n-1) 之间的差异约为 0.5-1k(这可能是因为框架重新创建了一些内容)并发布旧版本,例如,我可以注意到 CGDataProvider 的这一点)。无论如何,Heap(n+1)-Heap(n) 中的内容包含一些不相关的内容,例如 CSEvent、UITouchData 等,这些内容很可能分配给处理按钮点击。
您是在设备还是模拟器上执行测试?您重复此 ADM 循环多少次?后续堆之间的差异内容是什么?这很有趣,因为 300k 对我来说似乎太多了。
I've run your code on simulator and I can't see this behavior. Here are steps I performed:
1) Run app under 'Allocations' instrument.
2) Wait until it fully starts.
3) mark heap -> Heap(0)
4) a) allocate CATextLayer instances with
allocateAutoReleasedLayers:
b) deallocate with
deallocateAutoReleasedLayers:
c) mark Heap -> Heap(1)
operation 4 gives us a test pattern (Allocate-Deallocate-Mark heap), so
5) ADM(2) -> Heap(2)
6) ADM(3) -> Heap(3)
7) ADM(4) -> Heap(4)
...
Difference between Heap(n) and Heap(n-1) is about 2K when ADM(n) is performed and drops to 0.5-1k when ADM(n+1) is performed (this is probably because framework recreates some stuff and releases old one, I can notice this for CGDataProvider for example). Anyway stuff in Heap(n+1)-Heap(n) contains something irrelevant like CSEvent, UITouchData etc. which is most probably allocated to handle button taps.
Are you performing your test on device or simulator? How many times you repeat this ADM loop? What is the content of difference between subsequent heaps? This is interesting because 300k seems too much to me.