共有メモリオブジェクトを使用してftruncateがメモリを使用しないのはなぜですか?

共有メモリオブジェクトを使用してftruncateがメモリを使用しないのはなぜですか?

私は共有メモリオブジェクトを作成し、それを使用して、ftruncateシステムのリソース制限に関係なく、一見したところ任意のサイズを提供できることを発見しました。以下のコードはサイズを262TBに設定し、stat()そのサイズを報告します。しかし、262TBは私が/dev/shmインストールしたものよりも大きく、私のシステムには262TBのメモリやスワップを使用することはできません。 OOMエラーが発生すると予想しましたが、システムメモリ使用量に大きな変化はありませんでした。

ここで何が起こっているのでしょうか?ftruncateシステムリソース制限を超えるサイズが成功するのはなぜですか?ftruncate共有メモリオブジェクト(またはより一般的にはtmpfs)間に特別な相互作用があるとします。

import os
import _posixshmem
try:
    fd = _posixshmem.shm_open("test", os.O_CREAT | os.O_EXCL | os.O_RDWR, mode=0o600)
    os.ftruncate(fd, 52428800 * 5000000)
    print(os.stat(fd))
finally:
    _posixshmem.shm_unlink("test")
os.stat_result(st_mode=33152, st_ino=244, st_dev=24, st_nlink=1, st_uid=1000, st_gid=100, st_size=262144000000000, st_atime=1693167355, st_mtime=1693167355, st_ctime=1693167355)

答え1

システムftruncateコールが変更されました。長さファイルサイズではなくファイルサイズです。ls -s前後のファイルにftruncateを使用すると、実際のサイズが変更されていないことがわかります。

あなたがすることは、穴のあるファイルを作成することだけです。ホールは、ブロック(またはこの場合はメモリページ)が割り当てられていない未割り当て領域です。この状態のファイルまたは共有メモリセグメントを使用すると、ホールから読み取ることができます(すべてゼロを取得できます)、書き込みまでページは実際には割り当てられません。

もちろん、これらすべてのページに書き込もうとすると、システムメモリが不足してクラッシュする可能性があります。

答え2

そのメモリに何かが書き込まれるまで、物理メモリは必要ありません。したがって、あなたの行動が統計に現れる必要はありません。

より正確に言えば、すべてのページをまだ未使用としてマークするには少しのメモリが必要になることがありますが、1.これは統計に表示されない可能性があります。 2. 代わりに最後のページのページ数が記録される場合(ページのページ数) )、この状況ファイルを避けることができます。

この動作に頼るのはそれほど便利ではありません。

関連情報