cocoa - Memory Continues to Increase when Loading and Releasing NSImage -


i have problem application aggressively consumes memory "thrashing point" successive image file loads. example, consider following code, repeatedly loads , releases 15mb jpeg file (large file size test purposes):

nsurl *inputurl = [nsurl urlwithstring:@"file:///users/me/desktop/15mbjpeg.jpg"];   for(int i=0; i<1000; i++) {       nsimage *image = [[nsimage alloc] initwithcontentsofurl:inputurl];       [image release];   } 

it performs first several since there plenty of free system memory, system comes knees @ i'm calling "thrashing point." here, believe system relieves enough memory load next image, performance ends being slow. additionally, other applications run because system has free hogged, unused, memory.

what make sense me if allocate memory , have system free "real mem" statistic in activity monitor stays small rather heading gigabytes successive load/release iterations. in practice, may never end @ point, seems odd activity monitor "real mem" statistic exceeds other applications when actual resident memory required @ time small. thought sort of memory leak or caching issue, seems more related aggressive memory allocation in application , lazy memory freeing on system (not there's wrong if os has policy--if in fact way works). perhaps i'm missing altogether though.

is there better way repeatedly load images without hogging-and-not-proactively-relieving memory usage behavior? perhaps there way force application memory footprint down, or there way smarter how images loaded same objects or memory locations? goal load image, process (get thumbnail, change image format, etc), rid of in memory, , again--all without observed memory growth.

--

follow-up:

bavarious, thanks. wrapping nsautoreleasepool resolve iterative memory growth when loading same file:

nsurl *inputurl = [nsurl urlwithstring:@"file:///users/me/desktop/15mbjpeg.jpg"];   for(int i=0; i<1000; i++) {       nsautoreleasepool *apool = [[nsautoreleasepool alloc] init];     nsimage *image = [[nsimage alloc] initwithcontentsofurl:inputurl];       [image release];     [apool drain]; } 

however, not solve issue memory stays increased after image released (and nsautoreleasepool drained). example, when loading 15mb jpeg image, "real mem" memory jumps 8mb steady state 25mb , stays there. (my application has interface builder button has wired ibaction method invokes loop copied). expect after loop finishes (or if 1 image loaded , released) "real mem" statistic decrease nominal application level memory usage.

it seems reasonable other things in background can loaded when invoking nsimage functionality, can increase memory. however, different sized images (15mb, 30mb, 50mb, etc) increase memory proportionally in application, leads me believe it's more such allocation.

further, if try load separate images in succession (say, 15mbjpeg-1.jpg, 15mbjpeg-2.jpg, etc.) memory sometimes compounds each new image loaded. example, if 2 images loaded in succession, "real mem" memory usage application after loading/releasing 50mb, , never decreases--based on observation. behavior continues when loading subsequent images application can creep hundreds of mb of "real mem" memory usage after loading several large images.

interestingly, if reload same image on , on again, steady state memory not increase. indicate sort of caching that's going on? again, goal batch process through several different image files without growth in memory. in advance.

oh, , i'm looking heapshot analysis article atm, wanted @ least post progress , see if there's other input.

--

follow-up #2

bbum, great article. ran instruments allocations test program , did not find heap growth. on referenced blog post, approach to, 1) click "load , release image" button on interface builder interface (which invokes load/release behavior), 2) click "mark heap" several times every few seconds in instruments allocations, , 3) repeat 1) , 2).

using approach, heapshots consistently reported 0 bytes in heap growth column on time (3 clicks every 5 sec 15 seconds), meaning there no additional memory allocated baseline heapshot. additionally, in statistics pane, there malloc of 13.25mb each time click "load , release image" button, live bytes 0 bytes, meaning has been released. if click "load , release image" button 3 times, overall bytes image reports 39.75mb (3 * 13.25mb), meaning 39.75mb allocated, released since live bytes 0. allocations graph spikes , comes right down, since it's pretty quick operation. seems make sense there no leak , no growth in steady state use of memory.

but, do "real mem" statistic still high? know activity monitor not standard debugging memory issues. but, "real mem" still stays high until close program, , "real mem" goes "free" category, bizarre me.

i tested same approach 2 images (15mbjpeg-1.jpg, 15mbjpeg-2.jpg) duplicating code in same method, , observe no heap growth again. more allocations been made , released. however, "real mem" sits @ twice increase in case of loading , releasing 1 image. , again, doesn't decrease in test program's steady state.

is there further can do? here test code single image load/release wants give try (just wire ib button openfiles):

#import "testmemory.h" // declares -(ibaction) openfiles:(id)sender; @implementation testmemory -(ibaction) openfiles:(id)sender {     nsurl *inputurl = [nsurl urlwithstring:@"file:///users/me/desktop/15mbjpeg.jpg"];     nsautoreleasepool *apool = [[nsautoreleasepool alloc] init];     nsimage *image = [[nsimage alloc] initwithcontentsofurl:inputurl];     [image release];     [apool drain]; } @end 

thanks reading. :)

--

follow-up #3

bbum, no don't have garbage collection enabled (gc set unsupported in project settings). investigated memory using vmmap , vm tracker bar in instruments allocations. assumed meant vm tracker data when said vm instruments, since reports same information vmmap. after opening single image using "load , release image" button, significant memory numbers include following (from vm tracker):

type         %ofres  ressize  virtsize res%  %alldirty  dirtysize
__text       38%     33.84mb  80.45mb  42%   0%         0bytes
*dirty*     32%     28.23mb  114.99mb 24%   100%       17.11mb
malloc_large 14%     13.25mb  13.25mb  100%  0%         4kb
carbon       11%     9.86mb   9.86mb   100%  20%        3.46mb
vm_allocate  9%      8.43mb   48.17mb  18%   49%        8.43mb
...

interestingly, subsequent load/releases of single image increase "resident size" of dirty , vm_allocate types ~.3mb, , "dirty size" of these types increases on time. (vm_allocate seems subset of dirty). no other types appear change subsequent load/releases.

i unsure take away data, or how can use make program release memory. seems vm_allocate type may chunk not being freed, that's speculation. possible portion of underlying nsimage init implementation saves cache of image file , won't release it? again, stated earlier, intrigues me each subsequent load/release of same image file hardly consumes resources (cpu, disk grinding, etc) , wall clock time compared first load/release. in advance.

  • what bavarious said; have tried surrounding nsautoreleasepool.

  • that classic micro-benchmark. while indicates problem, problem may benchmark divergent expected real world patterns bug lies benchmark.

  • in efficiently designed application, not read same image data disk more once.

  • this prime candidate heapshot analysis.


(thanks follow-ups; helpful!)

the symptoms describe sound either vm leak (something consuming addresses without doing allocations; mapped memory, example) or cache isn't being pruned (that contains vm allocations).

  • do have gc enabled? if so, because gc threshold isn't triggered. collector doesn't know credit large allocations non-gc gc zone. if force collections, it'll work around particular edge case.

  • try having @ vm instrument or use vm_map @ command line have @ consuming address space within app.


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -