Note that there are some explanatory texts on larger screens.

plurals
  1. POPlease help find my memory leak
    primarykey
    data
    text
    <p>I have a simple Cocoa program to plot data read from a Raspberry Pi based server. After a few thousand reads, the programs memory usage pushes toward 1 GB. Each read simply gets a long integer for the time and a float value representing temperature read from a temperature sensor. I've removed everything that I can think of that might utilize memory and the problem does not change. Please tell me where my problem are.</p> <pre><code> // // ABSAppDelegate.m // RPi_socket_test // #import "ABSAppDelegate.h" #include &lt;sys/socket.h&gt; #include &lt;sys/types.h&gt; #include &lt;netinet/in.h&gt; #include &lt;netdb.h&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;errno.h&gt; #include &lt;arpa/inet.h&gt; @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)) &lt; 0) { NSLog(@"\n Error : Could not create socket \n"); ok = false; } memset(&amp;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", &amp;serv_addr.sin_addr)&lt;=0) { NSLog(@"\n inet_pton error occured\n"); } if( connect(sockfd, (struct sockaddr *)&amp;serv_addr, sizeof(serv_addr)) &lt; 0) { NSLog(@"\n Error : Connect Failed \n"); ok = false; } while ( (n = (int)read(sockfd, recvBuff, sizeof(recvBuff)-1)) &gt; 0) { recvBuff[n] = '\0'; [self performSelectorOnMainThread:@selector(displayTemp:) withObject:[NSString stringWithFormat:@"%.18s", recvBuff] waitUntilDone:YES]; } if(n &lt; 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 &lt; 1024) [txtSizeOfData setStringValue:[NSString stringWithFormat:@"%i Bytes", (int)dataSize]]; else if(dataSize &lt; 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 </code></pre> <p>With view controller</p> <pre><code> // // 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 </code></pre> <p>And subview controller</p> <pre><code> // // 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&lt;maxRawPlotData){ if(dataCount&gt;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&lt;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&lt;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&lt;dataCount; i++){ NSPoint testValue = myData[i]; if(testValue.x &gt; maxValue.x) maxValue.x = testValue.x; if(testValue.y &gt; 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&lt;dataCount; i++){ NSPoint testValue = myData[i]; if(testValue.x &lt; maxValue.x) maxValue.x = testValue.x; if(testValue.y &lt; maxValue.y) maxValue.y = testValue.y; } [pool drain]; return maxValue; } -(long int)SizeOfData{ long int dataSize = 0; for(int i=0; i&lt;dataCount; i++){ dataSize += sizeof(NSPoint); } return dataSize; } -(int)setMaxRawPlotData:(int)theMax{ if(theMax&lt;10) theMax = 10; maxRawPlotData = theMax; return (int)dataCount; } @end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload