Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

A hack for dealing with the fan/temperature issues in Lion

Lion is more resource-intensive than Snow Leopard and earlier versions, and this is part of the reason for why the temperature gets high and the fan runs more frequently in Lion.


Using the Activity Monitor, I see that after a short time of running after boot-up, more than 25% of my available memory is sitting in the "Inactive" state. This is memory that is released to the OS after applications run, but which is held for a period of time, or until the applications in question restart. This allows those applications to restart a little more quickly, at the cost of preventing other applications from using that memory while it's being held.


After a while, that Inactive memory gets freed, but until it does, that memory is unusable (unless any of the applications which previously held it will restart), and this can cause other running applications to have to swap on and off of disk because of a lack of available memory. This, in turn, causes the system to work harder, which means that the CPU gets hotter and the fan runs more.


In practice, the OS hangs onto that Inactive memory for a very long time, and the resulting ongoing swapping greatly contributes to the persistent and ongoing heat and fan issues. I'm guessing that this is a bug, and that Apple needs to change the logic that is used for freeing up Inactive memory in Lion, so this happens more frequently.


Until (unless?) Apple fixes this problem, I have come up with a hack that will periodically free memory from the Inactive pool if the total within that pool exceeds a specified amount. This gives the memory back to the OS and prevents swapping and a lot of the overheating. As a side effect, new applications might take a little longer to start up, but I find that this delay is barely noticeable, and it's well worth it in terms of improving the temperature and fan issues.


My hack involves a shell script combined with an AppleScript. For those of you who aren't familiar with one or both of these tools, here are detailed instructions for how to set everything up.


Open up the Finder and navigate to your home folder.


Create a sub-folder in your home folder called bin, if one doesn't already exist.


Create a sub-folder in your home folder called Applications, if one doesn't already exist.


Open up Text Edit and select File->New. Then, select Format->Make Plain Text.


In the open Text Edit window, enter the following text exactly as shown (except that you can change the tooMuchMem setting if you want). It's best to copy and paste it into the Text Edit window. Make sure that the #!/bin/bash line is the topmost line of the script, with no blank lines before it, and that the "#!" is in the leftmost column with no spaces before it:

#!/bin/bash


# Number of 4096-byte pages (50000 means 204,800 MB; you can change this) ...

tooMuchMem=50000


oldIFS="${IFS}"

IFS=:

/usr/bin/vm_stat 2>/dev/null \

| while read header mem

do

case "${header}" in

Pages\ inactive)

IFS="${oldIFS}"

mem="$(echo "${mem}" | /usr/bin/sed -e 's/\.//g' -e 's/ *//g')"

[[ ${mem} -gt ${tooMuchMem} ]] && {

echo -n "purging due to ${mem} inactive memory blocks > ${tooMuchMem} ..."

/usr/bin/purge

echo " done"

}

break

;;

esac

done 2>/dev/null


exit 0


Select File->Save...


In the save dialog box, navigate to the bin folder that you created to under your home folder.


Select Unicode (UTF-8) in the Plain Text Encoding box.


Un-check If no extension is provided, use ".txt".

Type releasemen in the Save As box.


Click Save and then quit from Text Edit.


Go to Finder and make sure there is now a file called releasemem in the bin sub-folder of your home folder.


Open Terminal. Type cd followed by the Return key to make sure you are in your home folder. Then, type this follwed by the Return key (it will set up releasemem to be an executable shell script). It's best to copy and paste this line into Terminal and then type the Return key.

chmod +x bin/releasemem


Close Terminal.


Now, open up AppleScript Editor. In the empty window which shows up, enter the following text exactly as shown (except that you can change the delayTime setting, if you want). It's best to copy and paste:

property homeDir : POSIX path of (path to home folder)

property delayTime : 60 (* seconds to wait between retries; you can change this *)


set releasemem to homeDir & "bin/releasemem"


repeat while true


do shell scriptreleasemem


delaydelayTime

end repeat



Click on compile (under the hammer icon), and then select File->Save As...


In the File Format menu in the save-as dialog box, select Application. Un-check all of the Options boxes.


Navigate to the Applications sub-folder of your home folder, and type ReleaseMem.app in the Save As box.


Click Save and then quit from AppleScript editor.


Open up System Preferences->Users & Groups. Select your login name and then click on Login Items.


Click the + (plus sign) button under the list of Login Items. Navigate to the Applications sub-folder of your home folder and select ReleaseMem.app.


Put a check in the box to the left of ReleaseMem.app in the Login Items list.


Now you can exit from System Preferences.


From now on, whenever you log in, the ReleaseMem application will start up. Every 60 seconds -- or whatever you specify within the AppleScript -- it will check whether your Inactive memory exceeds 50,000 blocks (204,800 MB) -- or whatever you specify in the releasemem script. If it exceeds that amount, the memory will be "purged"; i.e., released back to the OS.


I have done this, and I find that my fan hardly ever turns on any more, and that there is plenty of available memory.


I hope this works for you, although YMMV.

.

MacBook Pro, Mac OS X (10.7), Unibody MacBook Pro

Posted on Aug 8, 2011 8:22 AM

Reply
14 replies

Aug 8, 2011 9:13 AM in response to HippopotamusMan

This is nice. 🙂 I knew this could be set up I just didn't know how.


You are obviously on the same page as I am with this OS X memory management issue. Hopefully this gets addressed by Apple.


I'm going to contiue to study how OS X is handling this but I will definelty be using this hack if I need it, Thank you.


- I assume to remove the hack, one just needs to delete any files that were created?

Aug 8, 2011 9:24 AM in response to urabus

Thank you! 🙂


To remove the hack, just do this:


  • Go to System Preferences->Users & Groups.
  • Select your user ID, and then click on Login Items
  • Select the ReleaseMem.app entry in the Login Items list and then click on "-" (the minus sign) below the list.
  • Close System Preferences and restart.


You don't need to delete any of the items that are created. Removing ReleaseMem.app from the Login Items will prevent it from running from now on, after you restart.


And if you ever want to reinstate that program, you can just put it back into the Login Items.

.

Aug 8, 2011 3:11 PM in response to HippopotamusMan

I was too hasty when I wrote the AppleScript that I mentioned above. When doing a "repeat" forever, the system can't be shut down. I apologize for this error.


So now, I have changed the shell script and the AppleScript so that the looping is done within the shell script, and the AppleScript just launches the shell script in the background. This allows the system to shut down with no problem.


The instructions above haven't changed. Just use the following shell script and AppleScript instead of the ones I originally mentioned.


Shell script (now, change both the memory cutoff and the wait interval in this script):

#!/bin/bash


# Number of 4096-byte pages. 50000 is therefore 204,800 MB ...

tooMuchMem=50000

# Wait interval between retries, in seconds ...

waitInterval=60

base="${0##*/}"


lockf=~/var/run/${base}.lock


quit() {

/bin/rm -f ${lockf} 1>/dev/null 2>&1

exit ${1}

}


trap "quit 1" 1 2 3 15


/bin/mkdir -p ~/var/run 1>/dev/null 2>&1


/usr/bin/lockfile -1 -r0 ${lockf} 1>/dev/null 2>&1 || exit 1


while :

do

oldIFS="${IFS}"

IFS=:

/usr/bin/vm_stat 2>/dev/null \

| while read header mem

do

case "${header}" in

Pages\ inactive)

IFS="${oldIFS}"

mem="$(echo "${mem}" | /usr/bin/sed -e 's/\.//g' -e 's/ *//g')"

[[ ${mem} -gt ${tooMuchMem} ]] && {

echo -n "purging due to ${mem} inactive memory blocks > ${tooMuchMem} ..."

/usr/bin/purge

echo " done"

}

break

;;

esac

done

/bin/sleep ${waitInterval}

done




AppleScript (yes, it's only two lines now):

property releasemem : "(" & (POSIX path of (path to home folder)) & "bin/releasemem &) 1>/dev/null 2>&1"

do shell scriptreleasemem

.

Aug 8, 2011 3:53 PM in response to HippopotamusMan

Nice script indeed, I'm having similar problems. This really should be using launchd though, no? I was going to sit down tonight and address that 'saved state' problem with launchd and brutish force. Just because I like my phone, does not mean I want to have it's features on my MacBook!


I've noticed that even a restart will not stop the fans, it has to be off.


Really, quite disappointed in this update. It's not as bad as the Random System Shutdowns, but worse than any other.

Aug 8, 2011 6:41 PM in response to HippopotamusMan

I've now come up with a launchd-based solution for this. It's a lot cleaner than using AppleScript for starting the shell script.


Here's what to do ...


First, disable the Login Item for ReleaseMem.app as I described a few messages above.


Then, change the releasemem script, above, to look like this. As always, it's best to copy and paste:

#!/bin/bash


[[ $# -lt 1 ]] && exit 1


tooMuchMem="${1}"

shift


/bin/mkdir -p ~/var/run 1>/dev/null 2>&1


base="${0##*/}"

lockf=~/var/run/${base}.lock


quit() {

/bin/rm -f ${lockf}

exit ${1}

}


trap "quit 1" 1 2 3 15


/usr/bin/lockfile -1 -r0 ${lockf} 1>/dev/null 2>&1 || exit 1


oldIFS="${IFS}"

IFS=:

/usr/bin/vm_stat 2>/dev/null \

| while read header mem

do

case "${header}" in

Pages\ inactive)

IFS="${oldIFS}"

mem="$(echo "${mem}" | /usr/bin/sed -e 's/\.//g' -e 's/ *//g')"

[[ ${mem} -gt ${tooMuchMem} ]] && {

echo -n "purging due to ${mem} inactive memory blocks > ${tooMuchMem} ..."

/usr/bin/purge

echo " done"

}

break

;;

esac

done 2>/dev/null


quit 0


Open up Finder to your home folder.


Hold down the Option key and then click on the Go item in the Finder menu bar. While still holding down the Option key, select Library.


Create a sub-folder called LaunchAgents in this Library sub-folder, if one doesn't already exist.


Open up Text Edit and select File->New. Then, select Format->Make Plain Text.


Copy and paste this text into the Text Edit window:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

<dict>

<key>Label</key>

<string>XXX.releasemem</string>

<key>ProgramArguments</key>

<array>

<string>/Users/LLL/bin/releasemem</string>

<string>50000</string>

</array>

<key>StartInterval</key>

<integer>60</integer>

<key>StandardInPath</key>

<string>/dev/null</string>

<key>StandardOutPath</key>

<string>/dev/null</string>

<key>StandardErrorPath</key>

<string>/dev/null</string>

</dict>

</plist>


In this text, change the string XXX (in XXX.releasemem) to a dot-separated name that looks like a reverse domain name. For example, Apple uses com.apple (the reverse of the apple.com domain name). Pick something personal -- not anything like com.apple, com.google, etc. For this example, I'll use com.testorama. Therefore, in this example, the XXX.releasemem string will become com.testorama.releasemem.


In the text, change the string LLL (in /Users/LLL/bin/releasemem) to the login ID that you use when signing in to your Mac. For example, if your login ID is quack, then /Users/LLL/bin/releasemem will become /Users/quack/bin/releasemem.


You can also change the 50000 string and the 60 string if you want to modify the maximum number of 4096-byte Inactive memory blocks or the number of seconds between memory checks.


Select File->Save...


In the save dialog box, navigate to the Library sub-folder under your home folder, and then to the LaunchAgents sub-folder within Library.


Type XXX.releasemen.plist in the Save As box, where XXX is defined as above. In this example, the file name would be com.testorama.releasemem.plist.


Select Unicode (UTF-8) in the Plain Text Encoding box.


Un-check If no extension is provided, use ".txt".


Click Save and then quit from Text Edit.


Open the Terminal application.


Type these two commands, each followed by hitting the Return key. It's best if you copy and paste them one by one, each one followed by the Return key:

cd ~/Library/LaunchAgents

launchctl load -F XXX.releasemem.plist


XXX should be the same as above. In our example, the second command will be launchctl load -F com.testorama.relasemem.plist


That's it. Now, the releasemem command will run every 60 seconds (or whatever you specified in the plist file), and it will purge Inactive memory whenever it reaches the specified limit.

.

Aug 10, 2011 8:22 AM in response to John Hammer1

Rubbish. I think you must be talking about total beginners.


I'm pretty certain that my understanding of the OS is less than HippopotamusMa's, but that doesn't mean that I don't understand scripts/prefs files and how they work.


And what's the trouble copy/pasters can get themselves into? The worst that could happen is that it doesn't run/work, or what were you thinking of?

Aug 10, 2011 12:42 PM in response to John Hammer1

John Hammer1 wrote:


With all due respect, which I mean sincerely, no one with less than your own understanding of the OS should do this. Copy/Pasters are just going to get themselves in trouble.


I understand that this is complicated. However, I tried hard to make it as clear and foolproof as possible by going step by step instead of simply posting something like ...


  • Create the following executable shell script in ~/bin ... etc. ...
  • Create and load the following LaunchAgent plist in ~/Library/LaunchAgents ... etc. ...


That two-step procedure would be sufficient for some fairly experienced MacOSX programmers, but I wanted to spell things out in detail in order to try to help those who are not familiar with this kind of MacOSX programming.


I realize that what I wrote might still be daunting for many people, but I can't think of a better way to describe this procedure for those who might need some help.


In any case, if you think this can help you, then feel free to try it and to ask questions here if it doesn't seem to work.


If you feel it's too complicated, then don't try it.


But I agree with Redarm: if something goes wrong when you are trying to follow these steps, the worst that will happen is nothing.


Some day when I have enough spare time (but don't hold your breath!), I'll come up with a disk image that will install this hack. That will be much easier for most people.


Or if any of you are ambitious, feel free to create such a disk image ... or any other tools or procedures that might make this hack easier for people to install.

.

Dec 3, 2011 1:27 PM in response to HippopotamusMan

Thank you!


I've noticed over the past few days that my new MBP was running extremely low on RAM, with the excessive amounts (> 4 GB at points) sitting as Inactive. A quick google search told me that the 'purge' command would fix my problems. I was about to put together a small bash script that I was going to set a cron job up for, but this thread saved me the trouble!

Apr 7, 2013 8:30 AM in response to mbudofsky

Hi all,


I know this is a very old thread, but I'm interested in improving the scripts Hippo-Man posted. The thing with the original scripts is that they impose purging all the inactive memory at once, not a certain amount.


Do you know a way to achieve that? Purge freezes my MacBook Pro for about 30 seconds every time I activate it, and I'd like to avoid that... 😝

A hack for dealing with the fan/temperature issues in Lion

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.