Objective c 请帮我查找内存泄漏
我有一个简单的Cocoa程序来绘制从基于Raspberry Pi的服务器读取的数据。在几千次读取之后,程序内存使用量将向1GB推进。每次读取仅获取一个时间长整数和一个表示从温度传感器读取的温度的浮点值。我已经删除了所有我能想到的可能利用内存的东西,问题没有改变。请告诉我我的问题在哪里Objective c 请帮我查找内存泄漏,objective-c,cocoa,memory-leaks,Objective C,Cocoa,Memory Leaks,我有一个简单的Cocoa程序来绘制从基于Raspberry Pi的服务器读取的数据。在几千次读取之后,程序内存使用量将向1GB推进。每次读取仅获取一个时间长整数和一个表示从温度传感器读取的温度的浮点值。我已经删除了所有我能想到的可能利用内存的东西,问题没有改变。请告诉我我的问题在哪里 // // ABSAppDelegate.m // RPi_socket_test // #import "ABSAppDelegate.h" #include
//
// ABSAppDelegate.m
// RPi_socket_test
//
#import "ABSAppDelegate.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
@implementation ABSAppDelegate
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSView *superview = [[self window] contentView];
NSRect fullPlotFrame = [[self window] frame];
fullPlotFrame.size.height *= 0.75;
fullPlotFrame.size.width *= 0.85;
fullPlotFrame.origin.x = [[self window] frame].size.width*0.1;
fullPlotFrame.origin.y = [[self window] frame].size.height*0.02;
thePlot = [[[RPiViewController alloc] initWithFrame:fullPlotFrame] retain];
[superview addSubview:thePlot];
[thePlot display];
[NSThread detachNewThreadSelector:@selector(getTemp) toTarget:self withObject:nil];
}
-(void)getTemp{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
while(ok){
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
NSLog(@"\n Error : Could not create socket \n");
ok = false;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5001);
if(inet_pton(AF_INET, "172.27.220.44", &serv_addr.sin_addr)<=0)
{
NSLog(@"\n inet_pton error occured\n");
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
NSLog(@"\n Error : Connect Failed \n");
ok = false;
}
while ( (n = (int)read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = '\0';
[self performSelectorOnMainThread:@selector(displayTemp:) withObject:[NSString stringWithFormat:@"%.18s", recvBuff] waitUntilDone:YES];
}
if(n < 0)
{
NSLog(@"\n Read error \n");
}
close(sockfd);
sleep(1);
[pool drain];
}
}
-(void)displayTemp:(NSString*)theData{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSPoint pointForConversion = NSPointFromString(theData);
[txtTempC setStringValue:[NSString stringWithFormat:@"%0.0f, %0.2f", pointForConversion.x, pointForConversion.y]];
long int dataSize = [thePlot SizeOfData];
if(dataSize < 1024) [txtSizeOfData setStringValue:[NSString stringWithFormat:@"%i Bytes", (int)dataSize]];
else if(dataSize < 1024*1024) [txtSizeOfData setStringValue:[NSString stringWithFormat:@"%0.3f kBytes", (float)dataSize/1024]];
else [txtSizeOfData setStringValue:[NSString stringWithFormat:@"%0.3f MBytes", (float)dataSize/(1024*1024)]];
[thePlot addDataToPlot:pointForConversion];
[thePlot display];
[[self window] display];
[pool drain];
}
-(IBAction)getTemp:(id)sender{
if(!ok){
ok = true;
[NSThread detachNewThreadSelector:@selector(getTemp) toTarget:self withObject:nil];
}
}
-(IBAction)stopClient:(id)sender{
ok = false;
}
-(void)controlTextDidChange:(NSNotification *)obj{
if([obj object] == txtMax) [thePlot setMaxRawPlotData:(int)[txtMax integerValue]];
}
@end
和子视图控制器
//
// RPiViewController.m
// RPi_socket_test
//
#import "RPiViewController.h"
@implementation RPiViewController
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
fontSize = 10;
NSMutableDictionary *drawStringAttributes = [[NSMutableDictionary alloc] init];
[drawStringAttributes setValue:[NSColor blackColor] forKey:NSForegroundColorAttributeName];
NSFont *myFont = [NSFont fontWithName:@"American Typewriter" size:fontSize];
[drawStringAttributes setValue:myFont forKey:NSFontAttributeName];
NSString* strLabelWidth = [NSString stringWithFormat:@"%0.2f", 55.55];
float labelWidth = [strLabelWidth sizeWithAttributes:drawStringAttributes].width;
NSRect frameForData = [self bounds];
frameForData.origin.x += labelWidth;
frameForData.size.width -= labelWidth;
myPlot = [[[RPiView alloc] initWithFrame:frameForData] retain];
[self addSubview:myPlot];
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSPoint minPoint = [myPlot findMinValues];
NSPoint maxPoint = [myPlot findMaxValues];
NSMutableDictionary *drawStringAttributes = [[NSMutableDictionary alloc] init];
[drawStringAttributes setValue:[NSColor blackColor] forKey:NSForegroundColorAttributeName];
NSFont *myFont = [NSFont fontWithName:@"American Typewriter" size:fontSize];
[drawStringAttributes setValue:myFont forKey:NSFontAttributeName];
NSString* MinTempLabel = [NSString stringWithFormat:@"%0.2f", minPoint.y];
NSPoint pointToDrawLabel = {0,0};
[MinTempLabel drawAtPoint:pointToDrawLabel withAttributes:drawStringAttributes];
NSString* MaxTempLabel = [NSString stringWithFormat:@"%0.2f", maxPoint.y];
pointToDrawLabel.y = [self bounds].size.height - [MaxTempLabel sizeWithAttributes:drawStringAttributes].height;
[MaxTempLabel drawAtPoint:pointToDrawLabel withAttributes:drawStringAttributes];
[pool drain];
}
-(void)addDataToPlot:(NSPoint)theDataToPlot{
[myPlot addDataToPlot:theDataToPlot];
}
-(long int)SizeOfData{
long int dataSize = [myPlot SizeOfData];
return dataSize;
}
-(int)setMaxRawPlotData:(int)theMax{
return [myPlot setMaxRawPlotData:theMax];
}
@end
//
// RPiView.m
// RPi_socket_test
//
#import "RPiView.h"
@implementation RPiView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
maxRawPlotData = 3600;
firstRawPlotIndex = 0;
dataCount = 0;
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{ // Drawing code here.
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint minPoint = [self findMinValues];
NSPoint maxPoint = [self findMaxValues];
float xScale = ([self bounds].size.width)/(maxPoint.x - minPoint.x);
float yScale = [self bounds].size.height/(maxPoint.y - minPoint.y);
[[NSColor whiteColor] set];
NSRect fillArea = [self bounds];
[NSBezierPath fillRect:fillArea];
NSBezierPath *pathForPlot = [[NSBezierPath alloc] init];
if(dataCount<maxRawPlotData){
if(dataCount>1){
NSPoint p1 = myData[0];
p1.x = (p1.x-minPoint.x)*xScale;
p1.y = (p1.y-minPoint.y)*yScale;
[pathForPlot moveToPoint:p1];
}
for(int i=1; i<dataCount; i++){
NSPoint p = myData[i];
p.x = (p.x-minPoint.x)*xScale;
p.y = (p.y-minPoint.y)*yScale;
[pathForPlot lineToPoint:p];
}
}
else{
unsigned long firstPointToPlot = dataCount-maxRawPlotData;
NSPoint p1 = myData[firstPointToPlot];
xScale = [self bounds].size.width/maxRawPlotData;
minPoint.x = p1.x;
p1.x = (p1.x-minPoint.x)*xScale;
p1.y = (p1.y-minPoint.y)*yScale;
[pathForPlot moveToPoint:p1];
for(unsigned long i=firstPointToPlot; i<dataCount; i++){
NSPoint p = myData[i];
p.x = (p.x-minPoint.x)*xScale;
p.y = (p.y-minPoint.y)*yScale;
[pathForPlot lineToPoint:p];
}
}
[[NSColor blackColor] set];
[pathForPlot stroke];
[pool drain];
}
-(void)addDataToPlot:(NSPoint)theDataToPlot{
myData[dataCount] = theDataToPlot;
dataCount++;
}
-(NSPoint)findMaxValues{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint maxValue = {-1e9, -1e9};
for(int i=0; i<dataCount; i++){
NSPoint testValue = myData[i];
if(testValue.x > maxValue.x) maxValue.x = testValue.x;
if(testValue.y > maxValue.y) maxValue.y = testValue.y;
}
[pool drain];
return maxValue;
}
-(NSPoint)findMinValues{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint maxValue = {1e9, 1e9};
for(int i=0; i<dataCount; i++){
NSPoint testValue = myData[i];
if(testValue.x < maxValue.x) maxValue.x = testValue.x;
if(testValue.y < maxValue.y) maxValue.y = testValue.y;
}
[pool drain];
return maxValue;
}
-(long int)SizeOfData{
long int dataSize = 0;
for(int i=0; i<dataCount; i++){
dataSize += sizeof(NSPoint);
}
return dataSize;
}
-(int)setMaxRawPlotData:(int)theMax{
if(theMax<10) theMax = 10;
maxRawPlotData = theMax;
return (int)dataCount;
}
@end
//
//RPiView.m
//RPi_插座_测试
//
#导入“RPiView.h”
@实现RPiView
-(id)initWithFrame:(NSRect)帧
{
self=[super initWithFrame:frame];
如果(自我){
//这里是初始化代码。
maxRawPlotData=3600;
firstRawPlotIndex=0;
数据计数=0;
}
回归自我;
}
-(void)drawRect:(NSRect)dirtyRect
{//这里是绘图代码。
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
NSPoint minPoint=[self findMinValue];
NSPoint maxPoint=[self findMaxValues];
float xScale=([self-bounds].size.width)/(maxPoint.x-minPoint.x);
float yScale=[self-bounds].size.height/(maxPoint.y-minPoint.y);
[[NSColor whiteColor]set];
NSRect fillArea=[自边界];
[NSBezierPath fillRect:fillArea];
NSBezierPath*pathForPlot=[[NSBezierPath alloc]init];
如果(数据计数1){
n点p1=myData[0];
p1.x=(p1.x-minPoint.x)*xScale;
p1.y=(p1.y-minPoint.y)*yScale;
[pathForPlot-moveToPoint:p1];
}
对于(int i=1;iSo),在痛苦地一节一节地关闭代码之后,我在子视图控制器中跟踪到drawRect方法的泄漏。通过在任何地方添加NSAutoReleasePool并释放NSBezierPath,泄漏被堵塞
谢谢你给我一个“大声思考”的机会
- (void)drawRect:(NSRect)dirtyRect
{ // Drawing code here.
NSAutoreleasePool* uberpool = [[NSAutoreleasePool alloc] init];
NSPoint minPoint = [self findMinValues];
NSPoint maxPoint = [self findMaxValues];
float xScale = ([self bounds].size.width)/(maxPoint.x - minPoint.x);
float yScale = [self bounds].size.height/(maxPoint.y - minPoint.y);
[[NSColor whiteColor] set];
NSRect fillArea = [self bounds];
[NSBezierPath fillRect:fillArea];
NSBezierPath *pathForPlot = [[NSBezierPath alloc] init];
if(dataCount<maxRawPlotData){
if(dataCount>1){
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint p1 = myData[0];
p1.x = (p1.x-minPoint.x)*xScale;
p1.y = (p1.y-minPoint.y)*yScale;
[pathForPlot moveToPoint:p1];
[pool drain];
}
for(int i=1; i<dataCount; i++){
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint p = myData[i];
p.x = (p.x-minPoint.x)*xScale;
p.y = (p.y-minPoint.y)*yScale;
[pathForPlot lineToPoint:p];
[pool drain];
}
}
else{
unsigned long firstPointToPlot = dataCount-maxRawPlotData;
NSPoint p1 = myData[firstPointToPlot];
xScale = [self bounds].size.width/maxRawPlotData;
minPoint.x = p1.x;
p1.x = (p1.x-minPoint.x)*xScale;
p1.y = (p1.y-minPoint.y)*yScale;
[pathForPlot moveToPoint:p1];
for(unsigned long i=firstPointToPlot; i<dataCount; i++){
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPoint p = myData[i];
p.x = (p.x-minPoint.x)*xScale;
p.y = (p.y-minPoint.y)*yScale;
[pathForPlot lineToPoint:p];
[pool drain];
}
}
[[NSColor blackColor] set];
[pathForPlot stroke];
[pathForPlot release];
[uberpool drain];
}
-(void)drawRect:(NSRect)dirtyRect
{//这里是绘图代码。
NSAutoreleasePool*uberpool=[[NSAutoreleasePool alloc]init];
NSPoint minPoint=[self findMinValue];
NSPoint maxPoint=[self findMaxValues];
float xScale=([self-bounds].size.width)/(maxPoint.x-minPoint.x);
float yScale=[self-bounds].size.height/(maxPoint.y-minPoint.y);
[[NSColor whiteColor]set];
NSRect fillArea=[自边界];
[NSBezierPath fillRect:fillArea];
NSBezierPath*pathForPlot=[[NSBezierPath alloc]init];
如果(数据计数1){
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
n点p1=myData[0];
p1.x=(p1.x-minPoint.x)*xScale;
p1.y=(p1.y-minPoint.y)*yScale;
[pathForPlot-moveToPoint:p1];
[泳池排水沟];
}
对于(int i=1;i您想让我们查看所有这些吗?Peter,如果崩溃与释放或保留对象有关,那么我想说,请在您的xcode设置中启用僵尸(在左上方的编辑方案中,您将获得选项)。一旦启用相同的功能,它将有助于您分析崩溃。没有崩溃。它只会消耗更多内存。我想它一定是在客户端循环中。我对网络编程不熟悉,担心我可能会有一些我的知识库永远无法发现的漏洞。当您使用Le在Instruments下运行此代码时,您会发现什么aks模板?请务必尝试在“产品”菜单下运行Analyze。它将搜索某些类型的内存错误和其他错误。使用仪器和观察NSBezierPath堆积会发现它不那么痛苦。我对此不熟悉。我将对此进行一些研究。谢谢!