4 Replies
      Latest reply: Feb 13, 2017 1:15 AM by tringdev RSS
      tringdev Level 1 Level 1 (0 points)

        Hi All,

         

        I am using NSTask to execute an external binary and I have connected NSPipe to listen for the data. But the memory usage of my app is raising hugely at prolonged use, even before my binary execution is finished.

         

        How to reduce this and is there any alternate other than adding observers to listen for data from task.

         

        Thanks,

        Arul

        • Re: nstask waitForDataInBackgroundAndNotify taking huge memory
          eskimo Apple Staff Apple Staff (6,665 points)

          I can’t think of any obvious reason why -waitForDataInBackgroundAndNotify would consume vast quantities of memory.  If you run the Allocations instrument on the program while it’s doing this, what types of objects are being allocated?

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: nstask waitForDataInBackgroundAndNotify taking huge memory
              tringdev Level 1 Level 1 (0 points)

              Even after commenting out all the code I do in the data available call back method, the memory shoots up.

              Actually i am running 2 tasks and add a view controller as observer for both the tasks. Both the tasks run concurrently.

                • Re: nstask waitForDataInBackgroundAndNotify taking huge memory
                  eskimo Apple Staff Apple Staff (6,665 points)

                  Even after commenting out all the code I do in the data available call back method, the memory shoots up.

                  That’s interesting, but I’m still interested in hearing what type of objects are being allocated here.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                    • Re: nstask waitForDataInBackgroundAndNotify taking huge memory
                      tringdev Level 1 Level 1 (0 points)

                      here is the code snippet

                       

                      NSTask *fileCountTask = [NSTask new];

                          [fileCountTask setLaunchPath:launchPath];

                          [fileCountTask setArguments:@[@"-c", command]];

                       

                          NSPipe *outputPipe = [NSPipe pipe];

                          [fileCountTask setStandardInput:[NSPipe pipe]];

                          [fileCountTask setStandardOutput:outputPipe];

                          [fileCountTask launch];

                       

                          NSFileHandle *objectHandle=[outputPipe fileHandleForReading];

                          [objectHandle waitForDataInBackgroundAndNotify];

                       

                          if (!taskObserverArray)

                          {

                              taskObserverArray = [NSMutableArray array];

                          }

                          dispatch_semaphore_t sema = dispatch_semaphore_create(0);

                          id taskProgressObserver = [[NSNotificationCenter defaultCenter]

                                                     addObserverForName:NSFileHandleDataAvailableNotification

                                                     object:objectHandle

                                                     queue:[NSOperationQueue mainQueue]

                                                     usingBlock:^(NSNotification *note)

                                                     {

                                                         dispatch_semaphore_signal(sema);

                                                         dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

                                                         if (taskBlock)

                                                         {

                                                             dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

                                                                     taskBlock(note);

                                                             

                                                             });

                                                         }

                                                     }];

                       

                          id taskTerminationObserver = [[NSNotificationCenter defaultCenter]

                                                  addObserverForName:NSTaskDidTerminateNotification

                                                  object:fileCountTask

                                                  queue:[NSOperationQueue mainQueue]

                                                  usingBlock:^(NSNotification *note)

                                                  {

                                                      dispatch_semaphore_signal(sema);

                                                      dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

                                                      if (taskTerminationBlock)

                                                      {

                                                          taskTerminationBlock(note);

                                                      }

                                                  }];

                       

                      Here is the code inside my block

                       

                      @autoreleasepool {

                              NSData *outData = [note.object availableData];

                              NSString *outStr = @"";

                              if (outData.length)

                              {

                                  outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];

                              }

                            

                              if (outStr && outStr.length)

                              {

                                  NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:[outStr componentsSeparatedByString:@"\r"]];

                                

                                  if ([[tempArray objectAtIndex:0] length] <= 0) {

                                      [tempArray removeObjectAtIndex:0];

                                  }

                                

                                  if([[tempArray objectAtIndex:[tempArray count]-1]length]<=0)

                                  {

                                      [tempArray removeLastObject];

                                  }

                                

                                  NSInteger arrayCount = [tempArray count];

                                  NSInteger finalValue;

                                

                                  if (arrayCount >=2) {

                                      NSInteger lastBeforeValue=[[tempArray objectAtIndex:arrayCount-2]integerValue];

                                      NSInteger lastValue=[[tempArray objectAtIndex:arrayCount-1]integerValue];

                                    

                                      if(lastValue>lastBeforeValue)

                                          finalValue=lastValue;

                                      else

                                          finalValue=lastBeforeValue;

                                  }else{

                                      finalValue = [[tempArray firstObject]integerValue];

                                  }

                                  outStr = nil;

                                  tempArray = nil;

                                

                                      dispatch_async(dispatch_get_main_queue(), ^

                                                     {

                                                         [_delegate noofFilesToBeScanned:finalValue];

                                                         _totalNumberOfFilesToScan=finalValue;

                                                         _client.totalFilesToScanCount=finalValue;

                                                         [note.object waitForDataInBackgroundAndNotify];

                                                     });

                                  }

                                

                          }