NSImage and F_NOCACHE

  • Hi,

    Im using F_NOCACHE with fcntl just before loading the file up as an
    NSImage so the data does not get cached and memory stays down. Im
    doing this because im converting thousands of images ( eps, tif, psd,
    pdf, anything... ). Thing is, memory never comes down. I though it
    might be a memory leak or something so i brought the code down to this:

    int    err = 0;
    int    fd = open( [self cString], O_RDWR );
    err = fcntl(fd, F_NOCACHE, 1);
    NSImage*    img = [[NSImage alloc] initWithContentsOfFile:self];
    [img release];
    img = nil;

    If i comment out the NSImage line, memory stays down of course, as
    soon as i add it back in, memory goes way up. BTW, fcntl is always
    returning 0 so there are no errors. Any ideas what might be going on?

    thanks

    Alex
  • On Oct 4, 2006, at 8:48 AM, Alexander Cohen wrote:
    > Im using F_NOCACHE with fcntl just before loading the file up as an
    > NSImage so the data does not get cached and memory stays down. Im
    > doing this because im converting thousands of images ( eps, tif,
    > psd, pdf, anything... ). Thing is, memory never comes down. I
    > though it might be a memory leak or something so i brought the code
    > down to this:
    >
    >
    > int    err = 0;
    > int    fd = open( [self cString], O_RDWR );
    > err = fcntl(fd, F_NOCACHE, 1);
    > NSImage*    img = [[NSImage alloc] initWithContentsOfFile:self];
    > [img release];
    > img = nil;
    >
    >
    > If i comment out the NSImage line, memory stays down of course, as
    > soon as i add it back in, memory goes way up. BTW, fcntl is always
    > returning 0 so there are no errors. Any ideas what might be going on?

    The open/fcntl sequence have absolutely no impact upon the call to -
    initWithContentsOfFile:.  open opens a file descriptor and fcntl()
    applies an option to that file descriptor.  -initWithContentsOfFile:
    takes a string and opens the file itself;  it has no way of even
    getting a hold of the file descriptor you are creating, much less
    actually using it.

    Also, the -cString method is deprecated.  Use -
    fileSystemRepresentation.

    The above code implies that it is on a category of NSString?  That
    seems a bit odd, design pattern wise.

    You could probably use a combination of -initByReferencingFile: and -
    recache to get the memory management behavior you desire, but I'm not
    entirely sure about that.  I would suggest reading everything you can
    about NSImage.  Worse comes to worse, you might need to drop to one
    of the lower level image manipulation APIs.  Or try NSImageRep as it
    seems to be one step beyond the NSImage caching behavior.

    b.bum
  • -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    On Oct 4, 2006, at 10:48 AM, Alexander Cohen wrote:

    > Hi,
    >
    > Im using F_NOCACHE with fcntl just before loading the file up as an
    > NSImage so the data does not get cached and memory stays down. Im
    > doing this because im converting thousands of images ( eps, tif,
    > psd, pdf, anything... ). Thing is, memory never comes down. I
    > though it might be a memory leak or something so i brought the code
    > down to this:
    >
    >
    > int    err = 0;
    > int    fd = open( [self cString], O_RDWR );
    > err = fcntl(fd, F_NOCACHE, 1);
    > NSImage*    img = [[NSImage alloc] initWithContentsOfFile:self];
    > [img release];
    > img = nil;
    >
    >
    > If i comment out the NSImage line, memory stays down of course, as
    > soon as i add it back in, memory goes way up. BTW, fcntl is always
    > returning 0 so there are no errors. Any ideas what might be going on?
    >

    Your NOCACHE directive only applies to the fd you opened. NSImage is
    going to open it's own fd. In this case, you should read the file
    yourself into an NSData instance, and then use that to init an
    NSImage instance.

    Brian Bergstrand
    <http://www.bergstrand.org/brian/>  PGP Key ID: 0xB6C7B6A2

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.3 (Darwin)

    iD8DBQFFI/HgedHYW7bHtqIRAgVeAJ96QJCVnBx7CInMXDQxhWX/YFLv3wCg5pWZ
    JBM1SumBVIql05xm7K1NVFg=
    =LGLC
    -----END PGP SIGNATURE-----
  • On Wed, 4 Oct 2006 11:48:13 -0400, Alexander Cohen
    <alexcohen...> said:
    > Hi,
    >
    > Im using F_NOCACHE with fcntl just before loading the file up as an
    > NSImage so the data does not get cached and memory stays down. Im
    > doing this because im converting thousands of images ( eps, tif, psd,
    > pdf, anything... ). Thing is, memory never comes down. I though it
    > might be a memory leak or something so i brought the code down to this:
    >
    >
    > int err = 0;
    > int fd = open( [self cString], O_RDWR );
    > err = fcntl(fd, F_NOCACHE, 1);
    > NSImage* img = [[NSImage alloc] initWithContentsOfFile:self];
    > [img release];
    > img = nil;

    That's sort of like filling your car with gas and then driving away in a
    *different* car and then being surprised that it runs out of gas right away.
    Try it like this:

    NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:myFile];
    int fd = [fh fileDescriptor];
    fcntl(fd, F_NOCACHE, 1);
    fcntl(fd, F_RDAHEAD, 1);
    NSData* pictureData = [fh readDataToEndOfFile];
    [fh closeFile];

    Now you've got the picture data and can make an NSImage out of it.

    m.

    --
    matt neuburg, phd = <matt...>, <http://www.tidbits.com/matt/>
    A fool + a tool + an autorelease pool = cool!
    AppleScript: the Definitive Guide - Second Edition!
    <http://www.amazon.com/gp/product/0596102119>
  • On 4-Oct-06, at 2:38 PM, Matt Neuburg wrote:

    > On Wed, 4 Oct 2006 11:48:13 -0400, Alexander Cohen
    > <alexcohen...> said:
    >> Hi,
    >>
    >> Im using F_NOCACHE with fcntl just before loading the file up as an
    >> NSImage so the data does not get cached and memory stays down. Im
    >> doing this because im converting thousands of images ( eps, tif, psd,
    >> pdf, anything... ). Thing is, memory never comes down. I though it
    >> might be a memory leak or something so i brought the code down to
    >> this:
    >>
    >>
    >> int err = 0;
    >> int fd = open( [self cString], O_RDWR );
    >> err = fcntl(fd, F_NOCACHE, 1);
    >> NSImage* img = [[NSImage alloc] initWithContentsOfFile:self];
    >> [img release];
    >> img = nil;
    >
    > That's sort of like filling your car with gas and then driving away
    > in a
    > *different* car and then being surprised that it runs out of gas
    > right away.
    > Try it like this:
    >
    > NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:myFile];
    > int fd = [fh fileDescriptor];
    > fcntl(fd, F_NOCACHE, 1);
    > fcntl(fd, F_RDAHEAD, 1);
    > NSData* pictureData = [fh readDataToEndOfFile];
    > [fh closeFile];

    Its funny, im using your exact code modified like the following but
    memory still goes  way up.

    NSAutoreleasePool*    pool = [[NSAutoreleasePool alloc] init];

    > NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:myFile];
    > int fd = [fh fileDescriptor];
    > fcntl(fd, F_NOCACHE, 1);
    > fcntl(fd, F_RDAHEAD, 1);
    > NSData* pictureData = [fh readDataToEndOfFile];
    > [fh closeFile];

    NSImage*    img = [[NSImage alloc] initWithData: pictureData];
    [img release];
    img = nil;

    [pool release];
    pool = nil;

    Im not sure whats going on.

    AC
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today