我目前使用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