アムネシアFreeBSD

FreeBSDでメモリ割り当てがどのように機能するのか理解できませんでした。 有用なすべての種類のドキュメントのうち、覚えられているのは



何年もの間、LinuxはFreeBSDよりもスワップアウトを回避するのに優れた仕事をしたという都市の神話が広まっていますが、これは事実ではありません。 実際に発生していたのは、Linuxが未使用ページをコアに保持し、キャッシュおよびプロセスページに使用できるメモリを少なくしている間に、FreeBSDが未使用ページを積極的にページングしてディスクキャッシュを増やすことでした。




まあ、Linuxよりはましだし、はい。 私は気にしません。 しかし、最も誤解されているメモリ割り当てプロセスよりも悪いことに、 非アクティブなメモリが私を殺していました。 それは何であり、「それ」を無痛で使用することは可能ですか? このメモリをアプリケーションで使用できると見なすべきですか?



アンダーカットでは、答えよりも質問が多くあります。



FreeBSD FAQは次のことを報告しています

16.2。



実行中のプログラムが非常に少ない場合でも、topに空きメモリがほとんど表示されないのはなぜですか?



簡単な答えは、空きメモリは無駄なメモリであるということです。 プログラムが積極的に割り当てないメモリは、FreeBSDカーネル内でディスクキャッシュとして使用されます。 Inact、Cache、およびBufとしてラベル付けされた上部(1)で示される値は、すべて異なるエージングレベルのキャッシュデータです。 このキャッシュされたデータは、システムが最近アクセスしたデータのために低速のディスクに再度アクセスする必要がないことを意味し、したがって全体的なパフォーマンスが向上します。 一般に、上部(1)の[空きメモリ]に表示される値は、それほど低くない場合は低い値が適切です。




さて、それをあるレベルのキャッシュにしますが、このInactメモリをCacheに入れてみませんか? (多くのフォーラムユーザーによる)使用可能で、すぐにではなくても、リクエストに応じて割り当てることができるからでしょうか?



実用的な方法で調べてみましょう。 私たちが持っています:

# top -b 0 last pid: 1019; load averages: 0.21, 0.45, 0.24 up 0+00:03:33 14:26:30 28 processes: 1 running, 27 sleeping Mem: 18M Active, 17M Inact, 130M Wired, 24M Buf, 3756M Free Swap: 3852M Total, 3852M Free
      
      





つまり、ほとんどすべてのメモリが空きであり、スワップは完全に空きです。

次に、使用可能なメモリを使用するために、tmpfsパーティションを作成します。



 # mkdir /tmp/gb # mount -t tmpfs -o mode=01777,size=3221225472 tmpfs /tmp/gb # df -h | egrep "(Filesystem|tmpfs)" Filesystem Size Used Avail Capacity Mounted on tmpfs 3.0G 4.0K 3.0G 0% /tmp/gb
      
      







同時に

 # top -b 0 last pid: 1028; load averages: 0.09, 0.19, 0.17 up 0+00:09:30 14:32:27 28 processes: 1 running, 27 sleeping Mem: 18M Active, 17M Inact, 130M Wired, 24M Buf, 3756M Free Swap: 3852M Total, 3852M Free
      
      





パーティションは単純に作成/マウントされますが、無料なので、それにメモリを割り当てる必要はありません。

ファイルを入れてください。

 # dd if=/dev/urandom of=/tmp/gb/file.txt bs=1M count=3k 3072+0 records in 3071+0 records out 3220176896 bytes transferred in 53.334672 secs (60376801 bytes/sec) # df -h | egrep "(Filesystem|tmpfs)" Filesystem Size Used Avail Capacity Mounted on tmpfs 3.0G 3.0G 1.0M 100% /tmp/gb
      
      





3ギガバイトのメモリが占​​有されていますが、同時に

  # top -b 0 last pid: 1040; load averages: 0.19, 0.26, 0.20 up 0+00:16:40 14:39:37 28 processes: 1 running, 27 sleeping Mem: 18M Active, 3088M Inact, 137M Wired, 24M Buf, 677M Free Swap: 3852M Total, 3852M Free
      
      





何らかの理由で、それらはInactと見なされます。 ただし、アクティブではないため、干渉を試みます。 少し「Hello、world!」をスケッチして、メモリを割り当ててから解放します。

 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main (int argc, char *argv[]) { int i; char *buffer[64]; long lSize = 1024*1024*1024; int iMB = argc < 2 ? 1 : atoi(argv[1]); printf("iMB:\t%d\n", iMB); for(i=0; i < iMB; i++) { buffer[i] = (char*) malloc (lSize); if(buffer[i] != NULL) { printf("Alloc: %d\n", i); memset(buffer[i], 127, lSize); } else printf("Error!\n"); sleep(1); } sleep(10); for(i=0; i < iMB; i++) { printf("Free: %d\n", i); free (buffer[i]); } return 0; }
      
      







 # time ./a.out 3 iMB: 3 Alloc: 0 Alloc: 1 Alloc: 2 Free: 0 Free: 1 Free: 2 0.915u 1.475s 1:00.16 3.9% 5+168k 0+0io 0pf+0w
      
      





なぜそんなに長いの? おそらくInactiveにあると思われるtmpfsがスワップに圧縮されました。



実際、メモリを割り当てると(コードでは「sleep(10);」の瞬間)、次のように表示されます。

 # top -b 0 last pid: 1128; load averages: 0.02, 0.11, 0.14 up 0+00:28:34 14:51:31 37 processes: 1 running, 36 sleeping Mem: 3106M Active, 621M Inact, 155M Wired, 26M Cache, 27M Buf, 14M Free Swap: 3852M Total, 2502M Used, 1350M Free, 64% Inuse
      
      





しかし、それよりも悪い。 アプリケーションによってメモリを解放した後:

 # top -b 0 last pid: 1129; load averages: 0.09, 0.12, 0.15 up 0+00:28:48 14:51:45 36 processes: 1 running, 35 sleeping Mem: 33M Active, 621M Inact, 145M Wired, 26M Cache, 27M Buf, 3095M Free Swap: 3852M Total, 2502M Used, 1350M Free, 64% Inuse
      
      





スワップは引き続き関与しました。

ファイルアクセスInactでメモリを返しました

 # time dd of=/dev/zero if=/tmp/gb/file.txt bs=1M count=3k 3071+0 records in 3071+0 records out 3220176896 bytes transferred in 40.265654 secs (79973292 bytes/sec) 0.008u 3.796s 0:40.26 9.4% 22+154k 0+0io 0pf+0w # time dd of=/dev/zero if=/tmp/gb/file.txt bs=1M count=3k 3071+0 records in 3071+0 records out 3220176896 bytes transferred in 1.242623 secs (2591434941 bytes/sec) 0.000u 1.241s 0:01.24 100.0% 25+173k 0+0io 0pf+0w # top -b 0 last pid: 1144; load averages: 0.09, 0.12, 0.14 up 0+00:36:22 14:59:19 36 processes: 1 running, 35 sleeping Mem: 29M Active, 3077M Inact, 146M Wired, 4K Cache, 27M Buf, 669M Free Swap: 3852M Total, 2502M Used, 1350M Free, 64% Inuse
      
      





スワップが残った理由は不明です:2502M使用済み



しかし、これが正常であり、空きスワップがある場合、この使用済みメモリが非アクティブであると見なし、 Inactとしてマークすることができます。 スワップがない場合はどうなりますか? 関係するメモリがアクティブになることを望みます。

スワップを削除し、同様に3Gb tmpfsセクションをマウントして埋めます。

 # top -b 0 last pid: 1013; load averages: 0.58, 0.53, 0.29 up 0+00:05:03 15:11:46 34 processes: 1 running, 33 sleeping Mem: 21M Active, 3089M Inact, 138M Wired, 24M Buf, 673M Free Swap:
      
      





私たちの良心をクリアするには、トップが嘘をつかないようにしてください:

 # expr `sysctl -n vm.stats.vm.v_inactive_count` \* `sysctl -n vm.stats.vm.v_page_size` 3239620608
      
      





そして、スワップがないにもかかわらず、ビジーなメモリはまだアクティブではありません...アクティブではないので、アプリケーションで再び占有しようとします。

 # ./a.out 3 iMB: 3 Alloc: 0 Killed
      
      





Rt そして最後に:

 # top -b 0 last pid: 1026; load averages: 0.15, 0.22, 0.21 up 0+00:11:37 15:18:20 34 processes: 1 running, 33 sleeping Mem: 3102M Active, 1524K Inact, 138M Wired, 200K Cache, 24M Buf, 679M Free Swap: # expr `sysctl -n vm.stats.vm.v_inactive_count` \* `sysctl -n vm.stats.vm.v_page_size` 1720320
      
      







おそらく何らかの結論があるはずですが、そうではありません...



All Articles