MacBookSSD を載せたものの、SSD にしたことで容量が減ったし、読んだり書いたりしまくると性能が落ちそうなので、色々と設定をした。もはや読み書きによる性能低下は気にする必要はないっぽいけど、気休めということで。

方針としては以下のような感じ。

  • 無駄なものは消す
  • たくさん読み書きされるものは SSD 上に置かない
    • 容量が小さい + 消えてもいいもの: メモリ上に置く
    • 容量が大きいもの: 外付け HDD に置く

具体的には、以下の設定をした。

  • swap(dynamic_pager)を無効にする
  • hibernatemode 変更
  • 各種キャッシュを ramdisk に移動
  • iTunes 関連のディレクトリを外付け HDD に移動

swap(dynamic_pager)を無効にする、hibernatemode 変更

swap(dynamic_pager)を無効にする

メモリが 8GB に増えたし、余計な swapfile を勝手に作られるのもアレなので、無効にした。Snow Leopard では以下のようにして dynamic_pager を起動しないようにした後、システムを再起動すればいいようだ。

$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist

再起動した後 swapfile を消す。

$ sudo rm /var/vm/swapfile*

sysctl で、swap が無効になっていることを確認した。

$ sysctl vm.swapusage
vm.swapusage: total = 0.00M  used = 0.00M  free = 0.00M
hibernatemode 変更

デフォルトだと sleep 時にメモリの内容をディスクに書き込む(メモリと同サイズのファイル /var/vm/sleepimage を作成する)ので、ディスクに書き込まないようにする。

$ sudo pmset -a hibernatemode 0

hibernatemode の引数の数字の詳細は man に書いてあった。

$ man pmset
...

SAFE SLEEP ARGUMENTS
...
     0000 0001 (bit 0) enables hibernation; causes OS X to write memory state to hibernation image
     at sleep time. On wake (without bit 1 set) OS X will resume from the hibernation image. Bit 0
     set (without bit 1 set) causes OS X to write memory state and immediately hibernate at sleep
     time.

     0000 0010 (bit 1), in conjunction with bit 0, causes OS X to maintain system state in memory
     and leave system power on until battery level drops below a near empty threshold (This enables
     quicker wakeup from memory while battery power is available). Upon nearly emptying the bat-
     tery, OS X shuts off all system power and hibernates; on wake the system will resume from
     hibernation image, not from memory.
...
     hibernatemode = 0 (binary 0000) by default on supported desktops. The system will not back
     memory up to persistent storage. The system must wake from the contents of memory; the system
     will lose context on power loss. This is, historically, plain old sleep.

     hibernatemode = 3 (binary 0011) by default on supported portables. The system will store a
     copy of memory to persistent storage (the disk), and will power memory during sleep. The sys-
     tem will wake from memory, unless a power loss forces it to restore from disk image.
...

MacBook における hibernatemode のデフォルトは 3(bit 0 と bit 1 に1が立っている)で、以下の二つの合わせ技、という状態のようだ。

  • bit 0 に1が立っている == hibernation 有効
    • sleep 時にメモリの内容をディスクに書き込んで hibernate image(/var/vm/sleepimage) 作成、即 hibernation する
    • sleep から復帰するときは hibernate image から内容を読み込む
  • bit 1 に1が立っている == sleep 時、ある閾値以上バッテリ残量が残っている間はメモリの内容をディスクに書き込まないが、バッテリ残量が閾値以下になるとメモリの内容をディスクに書き込む

各種キャッシュを ramdisk に移動

ramdisk を使うためには ramdisk を作成した後、ファイルシステムを構築してマウントする。ファイルシステムを構築してマウントする方法には、いくつか選択肢があるようだ(他にもあるかも)。

ramdisk を作成する

hdid で ramdisk を作成することができる。ramdisk の容量はブロック数(1ブロック == 512 byte)で指定する。1GB の ramdisk を作りたかったので 1024 * 1024 * 1024 / 512 = 2097152 にした。

$ sudo hdid -nomount ram://2097152
/dev/disk3
newfs_hfs でファイルシステム構築、mount でマウント

newfs_hfs でファイルシステムを構築する。-v で名前を付けることができる。

$ sudo newfs_hfs -v tmppp /dev/disk3
Initialized /dev/rdisk3 as a 1024 MB HFS Plus volume

mount でマウントする。ディスクデバイスの後の引数で、マウントポイントを指定することができる。

$ mkdir /tmp/tmppp
$ sudo mount -t hfs /dev/disk3 /tmp/tmppp
newfs_hfs でファイルシステム構築、diskutil mount でマウント

ファイルシステムを構築する。

$ sudo newfs_hfs -v tmppp /dev/disk3
Initialized /dev/rdisk3 as a 1024 MB HFS Plus volume

diskutil mount でマウントする。マウントポイントは /Volumes/ファイルシステム構築時に指定した名前 になる。

$ sudo diskutil mount /dev/disk3
diskutil eraseDisk でファイルシステム構築 + マウント

diskutil eraseDisk は、ファイルシステムのフォーマット、マウントポイント、ディスクデバイス、を指定すると、ディスクデバイス上にファイルシステムを構築して、マウントポイントにマウントしてくれる。

$ sudo diskutil eraseDisk HFS+ tmppp /dev/disk3

上記のように実行すると、/dev/disk3 に HFS+ のファイルシステムを構築し、 /Volumes/tmppp にマウントされる。

何がちがうの?

mount でマウントすると、Finder から取り出せないようだ(強制的に…… もできない)。

このせいか、再起動やシャットダウンをすると、1分くらいかかる(タイムアウトするまで待たされている?)。コマンドラインを使えば umount した後、hdiutil detach することで、取り出す(というか、削除?)ことができる。

$ sudo umount /dev/disk3
$ sudo hdiutil detach /dev/disk3     
"disk3" unmounted.
"disk3" ejected.

umount の前に hdiutil detach はできないらしい。

$ sudo hdiutil detach /dev/disk3
"disk3" unmounted.
hdiutil: couldn't eject "disk3" - リソースが使用中です

他の違いを確認するべく、5 MB の ramdisk、/dev/disk3, /dev/disk4, /dev/diks5 を作って以下のようにした。

diskutil list と mount で確認する。

$ diskutil list
/dev/disk3
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                                                   *5.2 MB     disk3
/dev/disk4
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                            tmppp                  *5.2 MB     disk4
/dev/disk5
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *5.2 MB     disk5
   1:                  Apple_HFS tmppp                   5.2 MB     disk5s1

newfs_hfs でファイルシステムを構築するとパーティションが作られないが、diskutil eraseDisk でファイルシステムを構築するとパーティションが作られる。

$ mount
...
/dev/disk3 on /tmp/foobar (hfs, local)
/dev/disk4 on /Volumes/tmppp (hfs, local, nodev, nosuid, noowners)
/dev/disk5s1 on /Volumes/tmppp 1 (hfs, local, nodev, nosuid, noowners)

diskutil でマウントすると、nodev, nosuid, noowners というオプションが付く。といった感じか。これによって、何が変わるんだ……?

各種キャッシュを ramdisk に移動

とりあえず以下を ramdisk 上に置くことにした。

  • /private/tmp
  • /private/var/folders/Hs/HsEDZDoMF1uNrEutSd+kCE+++TI/-Tmp-
    • 汎用的な一時ファイルが置かれる(Preview.app で画像を開くとき、とか)
    • /private/var/folders 以下、Hs/HsEDZDoMF1uNrEutSd+kCE+++TI の部分はマシン毎に異なる
  • /private/var/folders/Hs/HsEDZDoMF1uNrEutSd+kCE+++TI/TemporaryItems
    • ブラウザで flash 動画を見るとき、一時的に動画ファイルが置かれる
  • /opt/local/var/macports/build
    • macports における、ビルド時の working ディレクト
    • 大きめのものをビルドすると割とすぐに溢れるので、あまりよくないかもしれない
      • 例: gcc をビルドしたら溢れた → 外付け HDD に移動 → 一時的に 3 GB を超えた……
  • /Users/nulll/Library/Application\ Support/Reeder/Caches
    • Reeder がキャッシュを保存する
  • /Users/nulll/Library/Caches/Adobe
    • flash が各種設定を保存する
  • /Users/nulll/Library/Caches/Chromium
    • Chromium がキャッシュを保存する
  • /Users/nulll/Library/Caches/Firefox
    • Firefox がキャッシュを保存する
  • /Users/nulll/Library/Caches/TemporaryItems
    • flash が一時的な情報を置く
  • /Users/nulll/Library/Caches/com.apple.Safari
    • Safari がキャッシュを保存する
  • /Users/nulll/Library/Caches/com.reederapp.mac.Reeder
    • Reeder がキャッシュを保存する
  • /Users/nulll/Library/Preferences/Macromedia
    • flash が各種設定を保存する

ramdisk 上に適当なディレクトリを作成して、上記ディレクトリを削除した後、シンボリックリンクする。

$ sudo rm -rf /opt/local/var/macports/build
$ mkdir /Volumes/tmp/mp_build
$ sudo ln -s /Volumes/tmp/mp_build /opt/local/var/macports/build
rc.local で起動時に実行する

ramdisk 作成、ファイルシステム構築、マウント、上述した各種ディレクトリからシンボリックリンクディレクトリの所有者変更、を起動時に行なうべく、/etc/rc.local として、以下のようなスクリプトを書いた。ファイルシステム構築 + マウントは、newfs_hfs + diskutil mount を使った。

#!/bin/sh

launchctl start com.apple.hdiejectd
sleep 3

rd=`hdid -nomount ram://2097152`
newfs_hfs -v tmp $rd
diskutil mount $rd

vol=/Volumes/tmp
while read src dst
do
  rm -rf $src
  mkdir -p $vol/$dst
  ln -s $vol/$dst $src
done <<SRC_DSTS
/private/tmp priv_tmp
/private/var/folders/Hs/HsEDZDoMF1uNrEutSd+kCE+++TI/-Tmp- var_tmp
/private/var/folders/Hs/HsEDZDoMF1uNrEutSd+kCE+++TI/TemporaryItems var_tmpitems
/opt/local/var/macports/build mp_build
/Users/nulll/Library/Application\ Support/Reeder/Caches cache_reeder_
/Users/nulll/Library/Caches/Adobe cache_adobe
/Users/nulll/Library/Caches/Chromium cache_chromium
/Users/nulll/Library/Caches/Firefox cache_firefox
/Users/nulll/Library/Caches/TemporaryItems cache_tmpitems
/Users/nulll/Library/Caches/com.apple.Safari cache_safari
/Users/nulll/Library/Caches/com.reederapp.mac.Reeder cache_reeder
/Users/nulll/Library/Preferences/Macromedia prefs_flash
SRC_DSTS

mkdir $vol/Downloads
chown -R nulll:wheel $vol

mount -u -o noatime /

launchctl start com.apple.hdiejectd; sleep 3 は、起動した後だと普通に ramdisk を作成することができるのに、rc.local に書くと ramdisk が作成されなかったので、http://moimoitei.blogspot.com/2010/11/use-ramdisk-on-macosx.html を参考にして入れた。

ついでに Dwonloads というディレクトリを作成して、Firefox におけるファイルのダウンロード先として使っている。

mount -u -o noatime / は、/ の最終アクセス時刻を更新しないようにすることで、SSD の書き込み回数が減ることを期待して入れた。無いよりはマシかもね、程度で、かなり気休め感が高い。

シングルユーザーモード

当初、rc.local 内のヒアドキュメントあたりで間違っていたらしく、起動はするが壁紙が表示されるだけで何もできない、という状況になった。ほんの一週間ちょっと前、HDD が壊れたときのあの悪夢再び……! みたいな感じで、泣きそうになりながらシングルユーザーモードで起動して、rc.local を編集した。

  • シングルユーザーモードで起動する
    • 電源を押して、ジャーンと鳴った後、command + s を押し続ける
  • シングルユーザーモードで起動すると、/ が readonly でマウントされているので、書き込めるようにする
# mount -uw /
  • 適当に編集したり、実行されないように移動したり消したりする

iTunes 関連のディレクトリを外付け HDD に移動

iTunes 関連のディレクトリ、以下の二つを外付け HDD に移動した。

  • /Users/nulll/Library/Application\ Support/MobileSync/Backup
    • iPhoneiPad のバックアップが作成される
  • /Users/nulll/Music/iTunes
    • iTunes のライブラリとか、iPhone のアプリケーションとかが置かれる

適当に移動した後、シンボリックリンクする

$ mv ~/Music/iTunes /Volumes/data/
$ rm -rf ~/Music/iTunes
$ ln -s /Volumes/data/iTunes ~/Music/iTunes
$ mv ~/Library/Application\ Support/MobileSync/Backup /Volumes/data/
$ rm -rf ~/Library/Application\ Support/MobileSync/Backup
$ ln -s /Volumes/data/iTunes/Backup ~/Library/Application\ Support/MobileSync/Backup

まとめ

今後もキャッシュっぽいディレクトリを発見し次第、ramdisk 上に置いていきたいところであるが、全体的に貧乏臭い感じの使い方であることは否めない。