小白是Emacs的忠實使用者,在CentOS伺服器上也要自己編譯安裝一個Emacs供自己使用。由于使用了很多Emacs的插件,每次啟動那是很緩慢的,幾乎是5s左右才打開一個檔案(讓大家誤以為伺服器配置很爛呢)。在打開檔案的速度上與Vim有些差距,Vim打開檔案幾乎是零等待(我這裡的vim是簡單的配置,并沒有使用額外的插件;使用Emacs的同行可不要罵我哦)。
最近發現Emacs的打開速度是巨慢無比的,之前就沒有這種問題。細想了一下,主要是之前有網絡連接配接,而這幾次是沒有網絡連接配接的。是以小白就想到底是Emacs的什麼插件需要用到網絡呢?于是使用了系統下的strace工具進行追蹤一下Emacs是如何啟動的,終于找到是什麼原因了,原來是主機名解析的問題,
在沒有聯網的情況下,啟動到底是多慢呢?
<code>[root@mydevops ~]</code><code># time emacs --kill</code>
<code>real 0m5.402s</code>
<code>user 0m0.367s</code>
<code>sys 0m0.019s</code>
看一下strace emacs的部分輸出,
<code># strace emacs</code>
<code>.......</code>
<code>open</code><code>(</code><code>"/etc/hosts"</code><code>, O_RDONLY|O_CLOEXEC) = 3 </code><code># 首先會檢視/etc/hosts檔案,在hosts檔案裡沒有找到關于系統主機名的解析</code>
<code>fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)</code>
<code>fstat(3, {st_mode=S_IFREG|0644, st_size=338, ...}) = 0</code>
<code>mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa6ae5a3000</code>
<code>read</code><code>(3, </code><code>"127.0.0.1 localhost.localdomai"</code><code>..., 4096) = 338</code>
<code>read</code><code>(3, </code><code>""</code><code>, 4096) = 0</code>
<code>close(3) = 0</code>
<code>munmap(0x7fa6ae5a3000, 4096) = 0</code>
<code>open</code><code>(</code><code>"/etc/ld.so.cache"</code><code>, O_RDONLY) = 3</code>
<code>fstat(3, {st_mode=S_IFREG|0644, st_size=49825, ...}) = 0</code>
<code>mmap(NULL, 49825, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fa6ae597000</code>
<code>open</code><code>(</code><code>"/lib64/libnss_dns.so.2"</code><code>, O_RDONLY) = 3</code>
<code>read</code><code>(3, </code><code>"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\20\0\0\0\0\0\0"</code><code>..., 832) = 832</code>
<code>fstat(3, {st_mode=S_IFREG|0755, st_size=27424, ...}) = 0</code>
<code>mmap(NULL, 2117880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fa6a7483000</code>
<code>mprotect(0x7fa6a7488000, 2093056, PROT_NONE) = 0</code>
<code>mmap(0x7fa6a7687000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x7fa6a7687000</code>
<code>open</code><code>(</code><code>"/lib64/libresolv.so.2"</code><code>, O_RDONLY) = 3</code>
<code>read</code><code>(3, </code><code>"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\00009\0\0\0\0\0\0"</code><code>..., 832) = 832</code>
<code>fstat(3, {st_mode=S_IFREG|0755, st_size=110960, ...}) = 0</code>
<code>mmap(NULL, 2202248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fa6a7269000</code>
<code>mprotect(0x7fa6a727f000, 2097152, PROT_NONE) = 0</code>
<code>mmap(0x7fa6a747f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7fa6a747f000</code>
<code>mmap(0x7fa6a7481000, 6792, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fa6a7481000</code>
<code>mprotect(0x7fa6a747f000, 4096, PROT_READ) = 0</code>
<code>mprotect(0x7fa6a7687000, 4096, PROT_READ) = 0</code>
<code>munmap(0x7fa6ae597000, 49825) = 0</code>
<code>socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3</code>
<code>connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr(</code><code>"127.0.0.1"</code><code>)}, 16) = 0 </code><code># 接着連接配接本地的53端口進行域名解析,随後sendto系統調用出現"Connection refused"的錯誤</code>
<code>poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])</code>
<code>sendto(3, </code><code>"w\265\1\0\0\1\0\0\0\0\0\0\10mydevops\0\0\1\0\1"</code><code>, 26, MSG_NOSIGNAL, NULL, 0) = 26</code>
<code>poll([{fd=3, events=POLLIN|POLLOUT}], 1, 5000) = 1 ([{fd=3, revents=POLLOUT|POLLERR}])</code>
<code>sendto(3, </code><code>"\32\205\1\0\0\1\0\0\0\0\0\0\10mydevops\0\0\34\0\1"</code><code>, 26, MSG_NOSIGNAL, NULL, 0) = -1 ECONNREFUSED (Connection refused)</code>
<code>connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr(</code><code>"127.0.0.1"</code><code>)}, 16) = 0</code>
<code>close(3)</code>
大家可以看到有很多“Connection refused”的錯誤資訊,在這些步驟中消耗了很多時間,最後逾時導緻的。不知道為什麼Emacs啟動時要解析這些資訊?
既然問題出現了,這裡的解決辦法是在/etc/hosts檔案裡加上了關于主機名的解析。果然問題解決了。另外以emacs的守護程序方式啟動,然後以emacsclient打開檔案也是飛快的。
在/etc/hosts裡添加了主機名解析後,打開Emacs的用時為:
<code>real 0m0.400s</code>
<code>user 0m0.378s</code>
是不是相差很多。
最後,關于Emacs的啟動速度問題,小白這裡總結了3種方法:
Emacs以daemon的方式先啟動(從emacs23版本開始支援),然後使用emacslient來編輯檔案,這樣的打開速度幾乎是秒開。
<code># 具體如何操作</code>
<code># emacs --daemon # 首先以daemon的方式啟動</code>
<code># emacsclient /etc/hosts # 然後就可以編輯檔案了</code>
2. 在/etc/hosts裡設定系統主機名解析
<code># hostname</code>
<code>mydevops</code>
<code>echo</code> <code>"192.168.56.101 mydevops"</code> <code>>> </code><code>/etc/hosts</code>
3. 不加載任何配置檔案進行啟動(定制的内容越多啟動越慢)
版權聲明:原創作品,如需轉載,請注明出處。否則将追究法律責任
本文轉自 bigstone2012 51CTO部落格,原文連結:http://blog.51cto.com/lavenliu/1755557