回收 Linux cached memory

最近常被問到,當程式讀取大量資料, kernel 會使用大量記憶體當 cache,又不會在記憶體不足時進行回收,造成程式無法執行。這時該怎麼辨?

方法一:

echo 1 > /proc/sys/vm/drop_caches
    or
sysctl -w vm.drop_caches=1

這會觸發 kernel 回收用於 cache 的記憶體。

方法二:

fcntl(fd, F_SETFL, O_DIRECT)

在程式裡,為 file descriptor 設上 O_DIRECT,使 filesystem 避免 cache 該檔案的內容。這適用於某些大檔案。例如,播放隨便就上 Giga bytes 的影片的 media player,就能在 file descriptor 設定 O_DIRECT,避免吃掉大量的系統記憶體。

方法三:

sysctl -w vm.vfs_cache_pressure=n  (n > 100)

這會使 kernel 更勤於回收 cache。

以上作為參考。

O_DIRECT 的用途

Defining Symbols - Autoconf

— Macro: AC_DEFINE_UNQUOTED (variable, value, [description])
— Macro: AC_DEFINE_UNQUOTED (variable)

Like AC_DEFINE, but three shell expansions are performed—once—on variable and value: variable expansion (‘$’), command substitution (‘`’), and backslash escaping (‘\’), as if in an unquoted here-document. Single and double quote characters in the value have no special meaning. Use this macro instead of AC_DEFINE when variable or value is a shell variable. Examples:

AC_DEFINE_UNQUOTED([config_machfile], ["$machfile"],
            [Configuration machine file.])
          AC_DEFINE_UNQUOTED([GETGROUPS_T], [$ac_cv_type_getgroups],
            [getgroups return type.])
          AC_DEFINE_UNQUOTED([$ac_tr_hdr], [1],
            [Translated header name.])

用 AC_DEFINE_UNQUOTED 來定義 C 裡面的 macro,它可以將 shell 變數直接展開。

也就是說,可以直接吃 AC_ARG_WITH 得到得 $withval 變數;而不是用 AC_DEFINE。

石頭閒語:Autoconf 檢查額外函數庫 - 樂多日誌

假設第三方廠商提供的SDK名稱為 mylib ,我們想要在 configure 中增加一個 --with-mylib 的參數項目,以便他人指定 mylib 的安裝路徑。當我們增加 --with-mylib 選用參數時,Autoconf 會自動在內部定義一個 with_mylib 變數代表它。所以當你下達 configure --with-mylib=/opt/local/mylib 時,在 Autoconf 內部便定義 with_mylib 之值為 /opt/local/mylib 。

如果需要參考的 lib/header 不是在標準所在,就可以用 AC_ARG_WITH 來接受輸入,就不用使用者指定 CPPFLAGS/LDFLAGS。

要記得 AC_ARG_WITH 要在 AC_CHECK_LIB 之前設定好 CPPFLAGS/LDFLAGS。

Safe Cflags/Intel - Gentoo Linux Wiki

Warning: GCC 4.2 and above support -march=native, which automatically detects the optimum settings to use based on your processor. -march=native also detects and applies additional settings beyond -march specific to your CPU, (eg. -msse4). Unless you have a specific reason not to (e.g. distcc cross-compiling), you should probably be using -march=native rather than anything listed below.