我目前使用GLKit来做一些OpenGL绘图。我创建了一个普通的UIViewController,然后在一个容器中添加一个GLKViewController子类来完成我的绘图。虽然一切运行良好,如果我让我的程序运行一段时间(也许15-30分钟),最终崩溃,并给我以下错误。在GLKViewController运行循环内创建自动释放对象导致malloc错误
malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
于是我打开了malloc_error_break断点,堆栈跟踪指向下面的代码。
-(NSArray*)meshes:(NSArray *)meshes sortedFromFrontToBack:(BOOL)sortedFromFrontToBack
{
NSMutableArray *sortedMeshes = meshes.mutableCopy;
[sortedMeshes sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
DSNode *mesh1 = obj1;
DSNode *mesh2 = obj2;
GLKVector3 depth1 = isnan(mesh1.boundingSphere.radius) ? mesh1.transformationState.position : mesh1.boundingSphere.center;
GLKVector3 depth2 = isnan(mesh2.boundingSphere.radius) ? mesh2.transformationState.position : mesh2.boundingSphere.center;
GLKMatrix4 mesh1ToCameraSpace = [mesh1 nodeToOtherNodeTransform:self];
GLKMatrix4 mesh2ToCameraSpace = [mesh2 nodeToOtherNodeTransform:self];
GLKVector3 depth1InCameraSpace = GLKMatrix4MultiplyVector3WithTranslation(mesh1ToCameraSpace, depth1);
GLKVector3 depth2InCameraSpace = GLKMatrix4MultiplyVector3WithTranslation(mesh2ToCameraSpace, depth2);
NSNumber *n1 = [NSNumber numberWithFloat:depth1InCameraSpace.z];
NSNumber *n2 = [NSNumber numberWithFloat:depth2InCameraSpace.z]; /* Breakpoint triggered here */
if(sortedFromFrontToBack)
{
return [n2 compare:n1];
}
return [n1 compare:n2];
}];
return sortedMeshes;
}
正如我所说,[NSNumber numberWithFloat:]调用引发malloc错误。这个方法每次从我的GLKViewController的drawInRect方法调用一次。基本上,我有一个类来跟踪我的相机和OpenGL将要绘制的网格物体,并将它们排列在相机空间中,从前到后用不透明网格物体排列,或者在绘制它们之前回到前面透明。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(self.clearColor.r, self.clearColor.g, self.clearColor.b, self.clearColor.a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DSDirector *director = [DSDirector sharedDirector];
for(DSMesh *mesh in director.opaqueMeshes)
{
[mesh draw];
}
/* The director class keeps track of my scene's cameras and meshes and calls the above method to return the scene's transparent meshes properly sorted */
for(DSMesh *mesh in director.transparentMeshes)
{
[mesh draw];
}
}
从我读过,自动释放池应该排在每次运行循环结束,所以我也不会想到,创造了一堆自动释放对象的每一帧是一个问题,他们都应该得到冲刷每一帧。我介绍了我的程序并检查了任何泄漏,但找不到任何漏洞,而且我还使用ARC,这可以最大限度地降低风险。当我分析它时,活动字节总数永远不会变化,尽管总体字节增长很快,并且没有发现泄漏。另外,didReceiveMemoryWarning从不会触发。我很难过。
嗯,看起来你是对的,autoreleased对象不是问题。照顾你指出的那些事情,我仍然遇到一个malloc错误,只是打破了另一个地方。这一次,我做了一些GLKVector3属性的手动KVO,并且堆栈跟踪结束于didChangeValueForKey:行,具有完全相同的malloc mmap错误。既然它看起来像是一个内存问题,我已经看过乐器中的Allocations/Leaks,并且一切看起来都很好,没有泄漏,活动字节的数量永远不会增长,只是不明白从哪里开始。 – Devin