Get Ram Information OSX - macos

I need to get RAM information like in system_profiler
but I can't find any API to get this on OS X system (10.9 and higher are supported only).
Previously I got the information from the system_profiler
NSTask *profilerTask = [[NSTask alloc] init];
[profilerTask setLaunchPath:#"/usr/sbin/system_profiler"];
And parsed it's output what what should I do if system profiler output language is not english ?
//Also it is slow as hell :(
Is there a good way to achieve the RAM hardware info
e.g. Number of slots , Ecc ,Type ,Bank, Speed ?

If you want to specifically get memory information try using:
NSTask *profilerTask = [[NSTask alloc] init];
[profilerTask setLaunchPath:#"/usr/sbin/system_profiler"];
[profilerTask setArguments:[NSArray arrayWithObjects:#"SPMemoryDataType",nil]];
By specifying the data type it should be quicker. To get a list of the available data types use:
$ system_profiler -listDataTypes

Related

How to compute 'purgeable' disk on APFS volume, on macOS?

My application needs to know the free space on a APFS volume.
It seems the operating system can 'reserve' purgeable disk space, starting from macOS High Sierra and APFS.
When using NSFileManager function, it only returns 'real' free space:
NSDictionary* pathAttrs = [[NSFileManager defaultManager] fileSystemAttributesAtPath: path];
NSNumber* pathSize = pathAttrs[ NSFileSystemSize];
NSNumber* pathFreeSize = pathAttrs[ NSFileSystemFreeSize];
My question: how to compute or estimate this 'purgeable' free space?

"Object controller", Entity mode: fetching is slow on Mavericks

It takes 5 seconds to load 8425 items on the last iMac.
I don't know what else add to provide you more info. I'm loading the items for the drop down list of a NSComboBox.
I've tested on Snow Leopard and Mountain Lion and it works fine. Tried on several machines, it works fine on all osx except for Mavericks. Same build and database files.
My guess is that NSComboBox loads all items one by one and CoreData has to make a roundtrip to the disk each time. You should inspect this situation with Instruments to know for sure what's going on.
Try prefetching all items before showing them. You can use -[NSFetchRequest returnsObjectsAsFaults:] property set to NO during such fetch.
Here's a snippet from my project that does prefetching:
if ( ! didPrefetch)
{
didPrefetch = YES;
// Your fetch request that will load all items
NSFetchRequest* fetchRequest = ... ;
// If you need to prefetch some relationships
fetchRequest.relationshipKeyPathsForPrefetching = #[...];
// This forces objects to fault info row cache
fetchRequest.returnsObjectsAsFaults = NO;
[managedObjectContext executeFetchRequest:fetchRequest error:&error];
}

RetainCount Memory not free'ed

I am stuck with the Cocoa Memory Managagment.
- (IBAction) createPush:(UIButton *)sender {
[create setEnabled:NO];
[release setEnabled:YES];
aLocation = [[Location alloc] init];
// Put some Example Stuff in the Class
aLocation.title = #"Apartment";
aLocation.street = #"Examplestreet 23";
aLocation.zip = #"12345";
aLocation.city = #"Exampletown";
aLocation.http = #"http://google.com";
aLocation.info = #"First Info Text";
aLocation.info2 = #"Second Info Text, not short as the first one";
aLocation.logoPath = #"http://google.de/nopic.jpg";
[aLocation.pictures addObject:#"http://google.de/nopic.jpg"];
[aLocation.pictures addObject:#"http://google.de/nopic.jpg"];
}
- (IBAction) releasePush:(UIButton *)sender {
[release setEnabled:NO];
[create setEnabled:YES];
[aLocation release];
aLocation = nil;
}
This Code works fine if I set or get Variables, but when I call the 'last' release (so the retain count is 0) it dealloc Method of aLocation gets called, but in Instruments Allocations you see that no memory is given back.
Here the Sources of Location:
http://homes.dnsalias.com/sof/Location.m
same Link with a '.h' instead of '.m' for the Header file (sorry its because of the Spaming Rule).
And the whole Project: http://homes.dnsalias.com/sof/Location.zip
Thanks for any help, where is my failure? Dennis
This Code works fine if I set or get
Variables, but when I call the 'last'
release (so the retain count is 0) it
dealloc Method of aLocation gets
called, but in Instruments Allocations
you see that no memory is given back.
What do you mean by "no memory is given back"?
Though oddly named, the memory management of aLocation is correct is the above code (assuming you have released it in dealloc as well).
Why doesn't memory use decrease when a single object is released?
(Paraphrased)
It is likely that your object is relatively tiny and, thus, that single deallocation falls below the ~20K or so needed to show up in Instruments.
If your app is crashing due to memory use issues, looking to a single deallocation is the wrong place to start. The first thing to do is to answer why your app is accreting memory and what is responsible for that growth.
Configure the Allocations instrument to only track live allocations. Then sort by total memory use. That'll show you what type of allocation is consuming the most memory. Start by reducing that.
Heapshot analysis can be very effective in these situations.
Additional Infos here because of maximum number of links and I have'nt the opportunity to post images...
What do you mean by "no memory is given back"?
I will show you the Instruments run, then it should be clear.
Screenshots from Instruments run
If want more Detail klick here for Instruments Run.
Your code is just fine. You are mistaken the output from Instruments. There is no Location object leaking.
For leaks, use the "Leaks" instrument. It won't fire. :-)

Working around NSFileHandle NSTask blocking when passing large amounts of data

I've got a bit of code that handles exporting data from my application. It takes in an NSString full of XML and runs it through a PHP script to generate HTMl, RTF, etc. It works well unless a user has a large list. This is apparently due to it overrunning the 8k or so buffer of NSPipe.
I worked around it (I think) in the readPipe and readHandle, but I'm not sure how to handle it in the writeHandle/writePipe. The application will beachball at [writeHandle writeData:[in... unless I break on it in gdb, wait a few seconds and and then continue.
Any help on how I can workaround this in my code?
- (NSString *)outputFromExporter:(COExporter *)exporter input:(NSString *)input {
NSString *exportedString = nil;
NSString *path = [exporter path];
NSTask *task = [[NSTask alloc] init];
NSPipe *writePipe = [NSPipe pipe];
NSFileHandle *writeHandle = [writePipe fileHandleForWriting];
NSPipe *readPipe = [NSPipe pipe];
NSFileHandle *readHandle = [readPipe fileHandleForReading];
NSMutableData *outputData = [[NSMutableData alloc] init];
NSData *readData = nil;
// Set the launch path and I/O for the task
[task setLaunchPath:path];
[task setStandardInput:writePipe];
[task setStandardOutput:readPipe];
// Launch the exporter, it will convert the raw OPML into HTML, Plaintext, etc
[task launch];
// Write the raw OPML representation to the exporter's input stream
[writeHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]];
[writeHandle closeFile];
while ((readData = [readHandle availableData]) && [readData length]) {
[outputData appendData:readData];
}
exportedString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
return exportedString;
}
There's a new API since 10.7, so you can avoid using NSNotifications.
task.standardOutput = [NSPipe pipe];
[[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
NSData *data = [file availableData]; // this will read to EOF, so call only once
NSLog(#"Task output! %#", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// if you're collecting the whole output of a task, you may store it on a property
[self.taskOutput appendData:data];
}];
Probably you want to repeat the same above for task.standardError.
IMPORTANT:
When your task terminates, you have to set readabilityHandler block to nil; otherwise, you'll encounter high CPU usage, as the reading will never stop.
[task setTerminationHandler:^(NSTask *task) {
// do your stuff on completion
[task.standardOutput fileHandleForReading].readabilityHandler = nil;
[task.standardError fileHandleForReading].readabilityHandler = nil;
}];
This is all asynchronous (and you should do it async), so your method should have a ^completion block.
NSFileHandle availableData seems to block infinitely:
I made a test program that I call with NSTask from another program. I assign the NSFileHandle to stdin and read the data from pipe. The test program floods the stdout with lots of text using NSLog function. There seems to be no way around it, no matter what API in the NSFileHandle I use, sooner or later the availableData blocks and then the app will hang infinitely and will do nothing. It actually stops to the data read statement, no matter if it is placed in the while or inside it. I tried also reading bytes, one by one, does not help
either:
data = [file readDataOfLength: 1]; // blocks infinitely
data = [file availableData]; // blocks infinitely
This works for a while until it also freezes. Seems that I have noticed that the NSFileHandle API does not really work with shell commands that output lots of data, so I have to work around this by using Posix API instead.
Every single example of how to read the data in parts with this API found from Stack Overflow or other sites in the Internet, either synchronously, or asynchronously, seems to block to last fileAvailableData read.
The simple, painful truth is that writing a lot of data to a subprocess and then reading a lot of data back from it is not something you can do in a single function or method without blocking the UI.
The solution is just as simple, and is certainly a painful-looking prospect: Make the export asynchronous. Write data as you can, and read data as you can. Not only are you then not blocking the UI, you also gain the ability to update a progress indicator for a really long export, and to do multiple exports in parallel (e.g., from separate documents).
It's work, but the UI payoffs are big, and the result is a cleaner design both internally and externally.
To be clear, this isn't just slow but it's actually freezing until you break in with a debugger? It's not a problem with your sub-process?
One would expect NSFileHandle to handle any data you throw at it, but perhaps you can split your data into smaller chunks using -subdataWithRange: to see what effect that has. You could also grab the fileDescriptor and use the POSIX APIs (fdopen, fwrite, etc.) to write to the stream. The POSIX APIs would provide more flexibility, if indeed that's what you need.
I believe what was happening was I was running into a deadlock caused by the [writeHandle writeData:[input dataUsingEncoding:NSUTF8StringEncoding]]; line filling overfilling its buffer and causing the application to hang until it is (never) emptied.
I worked around it by dispatching the write operation off to a separate thread.
Have a look at asynctask.m from this gist.
asynctask.m allows to process more than 8k of input data.

EXC_BAD_ACCESS in SQLite on Mac OS

I'm pulling and pushing data from an sqlite database. I use the FMDatabase cocoa wrapper.
I'm pulling and pushing data from multiple threads, but I made sure that more then one transactions never happen at the same time.
I get EXC_BAD_ACCESS after a few hundred call at the database but never at the same time. It's also not memory related (I've tried NSZombies and looked at the memory management of parameters).
Here is the stack and the code :
alt text http://grab.by/1VwY
FMResultSet* result = [db executeQuery:#"select latitude, longitude from cache where name = ?", name];
[result next];
NSString* latitude = [result stringForColumn:#"latitude"];
NSString* longitude = [result stringForColumn:#"longitude"];
I've got no idea, does somebody has one?
Looking through the relevant code in FMDatabase, it seems the sqlite_bind_text() routines uses the SQLITE_STATIC parameter to bind the result NSString's -UTF8String method (which returns an autoreleased pointer).
This means SQLite assumes that the text storage will remain valid for as long as the text remains bound, while the -UTF8String return is only valid for the current autorelease context. If you're using the same FMResultSet over multiple threads or function calls, changing that parameter to SQLITE_TRANSIENT would be much safer.
I'd suggest making that change in every sqlite3_bind_text() call and seeing if it still crashes. If that fixes it, you may want to report it back to the developer as a possible improvement.

Resources