-1

I need to retrieve the name of the most memory intensive application* on OS X. The solution should be in Objective-C while preferably refraining from using 3rd party APIs. The solution cannot contain any parsing.

*The memory intensity of an application can be defined as the amount of real memory in use by that application.

fdh
  • 5,256
  • 13
  • 58
  • 101
  • 1
    @JesseRusak Nothing. I have minimal experience with OSX, and unfortunately a Google search did not provide any relevant results. – fdh Aug 05 '12 at 17:04
  • Could you elaborate on what you mean by "most memory intensive"? – jscs Aug 05 '12 at 17:47
  • @JoshCaswell I have added in a few details that should clarify it. – fdh Aug 05 '12 at 17:52
  • 1
    I don't know the answer but, as a code example, the "top" utility should have source code available and it's able to do what you're asking. – Phillip Mills Aug 05 '12 at 17:54

3 Answers3

3

you can use sysctl to retrieve the available processes. the SO question "Can we retrieve the applications currently running in iPhone and iPad?" has an answer that should works for macOS … i tried it, simply putting the code in the answer in an Xcode 4.4 new macOS project, #importing and performing an NSLog on the result array rather than returning it, and it neatly displays the collected array of process names and IDs.

and while there is a wealth of information in struct kinfo_proc and its nested struct extern_proc, unfortunately for you, i don't see an easy way to retrieve the memory information for individual processes.

for that, you can consult libtop.c, which is Apple's open source offering. the linked version is from the MacOS X 10.8 library.

in any case, if you combine pulling the available processes from sysctl with the process information retrieval code in libtop.c, you should end up with a programmatic solution for exactly what you're looking for.

and … on the other hand … if you don't mind doing a very small bit of parsing compared to the work this will require, try the SO answer You can use NSTask , only substitute ps aux -m where that question performs "grep". you'll want to get only the first real line of output from the stream, and you'll have to parse whitespace to get to the column containing the RSS information, but that might be easier than getting what you want via libtop.c , depending upon what you need it for.

Community
  • 1
  • 1
john.k.doe
  • 7,533
  • 2
  • 37
  • 64
  • Could you refer me to a specific function in libtop.c? I went through the link but coulnd't find anything relevant. – fdh Aug 22 '12 at 02:42
  • the guts of what you will want to mimic is in file static function `libtop_p_task_update()`, which is called for every proc in file static function `libtop_p_proc_table_read()`, which is invoked from publicly available function `libtop_sample()`. you can either pull the code specific to your needs out of `libtop_p_task_update()` and not take all the rest of those statistics, or you can call `libtop_sample()`, and then figure out how to sort and get what you want out of the result of the calls to `libtop_tsamp()`. – john.k.doe Aug 22 '12 at 03:08
0

Bash is pretty good for things like this. Using bash you can have the command:

ps -p `ps aux | awk '{print $4,$2}' | sort -nr | head -n 1 | awk '{print $2}'` | awk '{print $4}' | tail -n 1

(could probably be optimised, but it still works)

Then do something like:

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"ps -p `ps aux | awk '{print $4,$2}' | sort -nr | head -n 1 | awk '{print $2}'` | awk '{print $4}' | tail -n 1"];

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

NSString *string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"Command Returned:\n%@", string);

[string release];
[task release];

The bash command works, the objective c code is untested though.

Dale Myers
  • 2,703
  • 3
  • 26
  • 48
  • The above code gives me a "launch path not accessible" error. Any idea what's wrong? – fdh Aug 21 '12 at 16:16
  • Have a look at Stuart's link above. That could do it. I don't have my Mac currently so I can't test anything. – Dale Myers Aug 21 '12 at 20:40
0
ps aux -m

will give you a print out of the processess in terms of memory (highest memory at the top). If you access this by pipeing this command then filtering the top line.

Developer docs on NSPipe

once you have it piped in all you have to do is exstract the bits you want(NSMutableString).

geminiCoder
  • 2,918
  • 2
  • 29
  • 50
  • Running the above command gives me a "launch path not accessible error". My code is identical to the one below, other than the fact it uses "ps aux -m" instead of ps -p `ps aux | awk '{print $4,$2}' | sort -nr | head -n 1 | awk '{print $2}'` | awk '{print $4}' | tail -n 1 Any idea what's wrong? – fdh Aug 21 '12 at 16:16
  • I think you need to tell it how to find the shell interpreter, as here: [nstask-launch-path-not-accessible](http://stackoverflow.com/questions/3221432/nstask-launch-path-not-accessible) – Stuart R. Jefferys Aug 21 '12 at 18:09