在Mac OS X上利用脚本实现RAM Disk

在如今内存白菜的时代, 动辄4G, 8G乃至更多的内存已经越来越常见, 但就目前来说, 在日常使用中, 大多数机器在绝大多数时间大量内存均处于闲置状态. 在这种情况下, 利用RAM Disk作为缓存以及存放临时文件就成了一种十分有效的提升性能的方法. 在Windows平台, RAM Disk的软件早已是遍地开花, 使用起来也是相当便利. 相比之下, 在Mac/Linux上, 这方面的软件就匮乏多了. 即使在应用相对丰富的Mac OS X上, 好用的RAM Disk软件也是寥寥无几, 而且大多需要收费. 不过好在有Unix-like OS强大的命令行, 再配合之脚本, RAM Disk的功能, 同样能够非常完美地实现, 并且开源而又环保.

下面便是我在Mac OS X Lion 10.7.3下, 利用bash shell脚本实现RAM Disk的全过程:

实现目标:

a. 用户注销时自动将当前内存盘的内容备份至dmg文件保存.

b. 用户登录时自动创建并挂载内存盘, 并从备份的dmg文件恢复保存的数据.

注意: 以下所有的操作需均需要在”终端”中进行, 并且需要获取root权限. (不想每次加上sudo的可以先运行”sudo -s”)

1. 写LoginHook脚本:

#!/bin/sh

# 设置内存盘的名称
DISK_NAME=RamDisk
MOUNT_PATH=/Volumes/$DISK_NAME
# 设置备份dmg文件的保存路径, 如使用默认请注意修改下面路径中的用户名称
BAK_DMG_PATH=/Users/delta/$DISK_NAME.dmg
# 设置分配给内存盘的空间大小(MB)
DISK_SPACE=2048

if [ ! -e $MOUNT_PATH ]; then
	diskutil erasevolume HFS+ $DISK_NAME `hdiutil attach -nomount ram://$(($DISK_SPACE*1024*2))`
fi

if [ -s $BAK_DMG_PATH ]; then
	asr restore -source $BAK_DMG_PATH -target $MOUNT_PATH -erase -noverify -noprompt
fi

这里我将此脚本存至 /etc/LoginHook/initramdisk.sh (具体目录及脚本名称可自定义, 但注意与后面的操作对应)

提示: OS X系统相对win7来说对于自身对于内存容量的要求高不少, 因此不建议在<4G内存的配置下使用内存盘. 另外, 脚本中”DISK_SPACE”变量设定的空间大小是内存盘的最大可用空间, 其实际占用的内存量是根据内存盘中存放数据的多少而动态增加的, 这点不同与Windows下的ramdisk软件.

2. 写LogoutHook脚本:

#!/bin/sh

# 设置内存盘的名称
DISK_NAME=RamDisk
MOUNT_PATH=/Volumes/$DISK_NAME
# 设置备份dmg文件的保存路径, 注意修改下面路径中的用户名称
BAK_DMG_PATH=/Users/delta/$DISK_NAME.dmg

# 下面使用UDZO格式(zlib)对备份dmg档进行压缩, 可大大减少备份文件的体积
# 但在内存盘中数据较多时可能影响速度, 可用UDRW代替(不压缩)
if [ -e $MOUNT_PATH ] ; then
	hdiutil create -srcdir $MOUNT_PATH -format UDZO -volname $DISK_NAME -ov $BAK_DMG_PATH
fi

这里我将此脚本存至 /etc/LogoutHook/syncramdisk.sh (具体目录及脚本名称可自定义, 但注意与后面的操作对应)

3. 为脚本加上可执行权限(路径请自行修改):

bash-3.2# chmod u+x /etc/LoginHook/initramdisk.sh
bash-3.2# chmod u+x /etc/LogoutHook/syncramdisk.sh

并设置其成为login/logout hook实现自动执行:

bash-3.2# defaults write com.apple.loginwindow LoginHook /etc/LoginHook/initramdisk.sh
bash-3.2# defaults write com.apple.loginwindow LogoutHook /etc/LogoutHook/syncramdisk.sh

此时注销并重新登录, 在Finder中便能看到新创建的ramdisk了.

4. 最后一步, 即是将缓存及临时文件转移到内存盘上. 可以使用符号链接的方式(在Mac下被称作”替身”). 比如下面的操作是将Chrome的缓存转移至内存盘中:

Delta-Notebook:~ delta$ mv ~/Library/Application\ Support/Google/Chrome /Volumes/RamDisk/
Delta-Notebook:~ delta$ ln -s /Volumes/RamDisk/Chrome ~/Library/Application\ Support/Google/Chrome

作为Mac来说, 无论是系统级还是用户级均存在着大量的缓存, 一般来说, ~/Library/Cache 中存在着不少用户程序的缓存. 对于那些IO较为密集的程序来说, 将它们的缓存转移至内存盘中, 其加速效果时相当明显的.

未来的计划:

1. 写一个一键安装/设置脚本简化步骤.

2. 实现GUI进一步方便普通用户操作.

21 thoughts on “在Mac OS X上利用脚本实现RAM Disk

  1. Google Chrome 18.0.1025.142 Google Chrome 18.0.1025.142 Windows 7 Windows 7
    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.142 Safari/535.19

    ^^

    1. Google Chrome 19.0.1084.15 Google Chrome 19.0.1084.15 Windows 7 x64 Edition Windows 7 x64 Edition
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.15 Safari/536.5

      miao~

  2. Google Chrome 18.0.1025.151 Google Chrome 18.0.1025.151 Mac OS X  10.7.3 Mac OS X 10.7.3
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19

    请问下,你的这个脚本和实现原理和 http://www.v2ex.com/t/11184 或http://www.fuzhijie.me/?p=657差别在哪里,那种方式更好呢?

    1. Google Chrome 19.0.1084.15 Google Chrome 19.0.1084.15 Windows 7 x64 Edition Windows 7 x64 Edition
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.15 Safari/536.5

      谢谢支持! 创建及挂载Ramdisk的原理几乎一样, 只是这两篇文章给出的脚本使用了较老的方式进行创建, 而使用hdiutil create命令是Apple现在推荐的方式. 只就Ramdisk的效果来说应该是一样的. 另外, 我的脚本进一步完善了注销/登录时的自动执行以及实现了Ramdisk数据备份.

  3. Google Chrome 18.0.1025.151 Google Chrome 18.0.1025.151 Mac OS X  10.7.3 Mac OS X 10.7.3
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19

    期待楼主的一键安装脚本和GUI功能
    。。。谢谢

    1. Google Chrome 20.0.1096.1 Google Chrome 20.0.1096.1 Windows 7 x64 Edition Windows 7 x64 Edition
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1096.1 Safari/536.6

      不客气啦~ 脚本倒是快搞定了, 只是最近事情实在太多还没来得及全部完成. GUI的话估计是得等到七八月份了…

  4. Google Chrome 18.0.1025.165 Google Chrome 18.0.1025.165 Mac OS X  10.7.3 Mac OS X 10.7.3
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.165 Safari/535.19

    楼主,我又来问一下,我想开机的时候创建ramdisk,然后加载~/Library/Cache 系统的缓存到ramdisk中,然后关机了不保存,这样会不会有问题。比如说,下次打开的时候恢复原有的程序窗口。还有就是这么做加速明显吗(我看到chrome的缓存目录貌似也在系统缓存目录下)。我以前在windows下用ramdisk plus,刚用mac小白,请教下。

    之前我也尝试过另外一种方案,详见http://www.guomii.com/posts/24462 不过发现开机的时候进入桌面后那个脚本才运行,比较慢,都能看到在眼前一闪。。

    1. Google Chrome 20.0.1105.0 Google Chrome 20.0.1105.0 Mac OS X  10.7.3 Mac OS X 10.7.3
      Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.8 (KHTML, like Gecko) Chrome/20.0.1105.0 Safari/536.8

      你好!
      1. 我测试了一下, ~/Library/Cache下的那些缓存文件多数是Apple自有程序的运行缓存, 体积较小, 访问频率貌似也不高. 如果放在ramdisk中并且不设置关机保存的话可能会导致部分缓存的重复创建, 这样反而失去了cache的意义了. Chrome的缓存主要是在~/Library/Application Support/Google/Chrome中, 参照最后一步转移到ramdisk就好了.
      2. AppleScript是将脚本编译成了app运行, 所以自然能看到其被自动执行时出现在dock中, 而Loginhook是完全后台执行的. 除此之外, 基本的原理都是一致的.
      3. 关于ramdisk中应该放的东西, 转移浏览器缓存效果是比较明显的, 另外还有xcode的工作文件夹等, 得看个人的需要了. 当然如果是ssd的话, ramdisk对于性能的提升作用可以就不会那么明显了…

  5. Google Chrome 18.0.1025.165 Google Chrome 18.0.1025.165 Mac OS X  10.7.3 Mac OS X 10.7.3
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.165 Safari/535.19

    谢谢,又有两个疑问
    1.我发现了通过finder找到的Library/Application Support下没有google,程序也很少。但是通过terminal cd过去的话可以看到。有点纳闷。感觉真正的目录是~/Library/Application Support/Google/Chrome
    2.查找etc下的目录,这个loginhook目录是需要自己创建的吧。我这儿没有。/etc/LogoutHook/

    1. Google Chrome 20.0.1115.1 Google Chrome 20.0.1115.1 Windows 7 x64 Edition Windows 7 x64 Edition
      Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.9 (KHTML, like Gecko) Chrome/20.0.1115.1 Safari/536.9

      Chrome的缓存的确是在 ~/Library/Application Support/Google/Chrome 中, 这个目录是在用户家目录下的. 而/Library/Application Support这个目录是系统目录.
      至于Loginhook脚本的位置, 其实是随意的. 只是我把它放在了/etc/LoginHook和/etc/LogoutHook这两个文件夹里了.

  6. Google Chrome 23.0.1271.64 Google Chrome 23.0.1271.64 Mac OS X  10.8.2 Mac OS X 10.8.2
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

    請問一下,那我該怎麼修改以下這程式呢?

    do shell script ”
    if ! test -e /Volumes/RamDisk ; then
    diskutil erasevolume HFS+ RamDisk `hdiutil attach -nomount ram://$((4*1024*1024*2))`
    fi

    1. Google Chrome 24.0.1312.5 Google Chrome 24.0.1312.5 Mac OS X  10.8.2 Mac OS X 10.8.2
      Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17

      您的语句似乎并无错误,运行起来有什么错误提示么?

      1. Google Chrome 23.0.1271.64 Google Chrome 23.0.1271.64 Mac OS X  10.8.2 Mac OS X 10.8.2
        Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

        這似乎並沒有錯,我想問的是

        do shell script ”
        #裡面打的是內容??

        問題之二:
        在用自製的ramdisk時,很容易睡眠後就消失,請問版主login和logout是在防止這些事情的發生嗎?

        問題之三:
        因為我大多數下載東西時,都是存在ramdisk,有方法用applescript來對指定的副檔名或資料夾做備份嗎?

        1. Google Chrome 24.0.1312.5 Google Chrome 24.0.1312.5 Mac OS X  10.8.2 Mac OS X 10.8.2
          Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17

          1. 是的,将shell命令放在引号里即可。
          2. loginhook与logouthook的方式目的是实现创建与备份ramdisk操作的自动化,每次用户登录和注销的时候都会执行对应的script。您说的睡眠后消失是指在suspend to RAM(sleep)还是suspend to disk(hibernate)后呢?
          3. 如果要实现备份ramdisk的自动化,建议还是用logouthook或者是shutdown script(/etc/rc.shutdown.local)的方式。applescript在这里可能有些大材小用了。

          1. Google Chrome 23.0.1271.64 Google Chrome 23.0.1271.64 Mac OS X  10.8.2 Mac OS X 10.8.2
            Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11

            suspend to RAM(sleep)和suspend to disk(hibernate),請聞一下差別在哪?
            我記得是我是講MBP闔上後。

          2. Google Chrome 25.0.1323.1 Google Chrome 25.0.1323.1 Mac OS X  10.8.2 Mac OS X 10.8.2
            Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.19 (KHTML, like Gecko) Chrome/25.0.1323.1 Safari/537.19

            suspend to ram就是传统意义上的sleep,就是保持内存通电,其他主要部件均处于关闭状态。而suspend to disk则是将内存当前内容保存到硬盘后完全断电。
            MBP盒盖之后默认是hybrid sleep,也就是在sleep的同时也将内存内容写入硬盘sleepimage文件中。
            我目前只用到sleep,倒是没有遇到这个问题。推测可能与hibernate有关。
            建议可以用一个叫做“Deep Sleep”的插件或终端命令设置一下睡眠模式试试。

    1. Google Chrome 24.0.1312.5 Google Chrome 24.0.1312.5 Mac OS X  10.8.2 Mac OS X 10.8.2
      Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17

      是的~ 关于ramdisk其实有不少开源或是闭源的软件。只是既然明白了其中原理,自己写一个练习也不错~

  7. Firefox 17.0 Firefox 17.0 Mac OS X  10.8 Mac OS X 10.8
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0

    Delta很厉害啊!开始我在App Store里买了个iRamDisk,却发现不能保存,果断退款,郁闷坏了,其实RamDisk的创建这个比较容易,就是保存方法不知道怎么弄,这篇文章帮大忙了~这样的话以后运行程序就舒服太多啦~~

    1. Google Chrome 23.0.1271.97 Google Chrome 23.0.1271.97 Windows 8 x64 Edition Windows 8 x64 Edition
      Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11

      不必客气,相互学习~

  8. Google Chrome 29.0.1547.65 Google Chrome 29.0.1547.65 Mac OS X  10.8.5 Mac OS X 10.8.5
    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36

    不知道撸主有完成TODO的部分吗?真心期待啊!

Leave a Reply to cch Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.