2011-11-11 6 views
1

私が理解しているように、ゼロメモリを割り当てようとするcallocと、オンデマンドでメモリを割り当てることができるの中から選択する必要があります。ゼロメモリをレイジーに割り当てる方法は?

これらのプロパティを組み合わせた関数はありますか?おそらくmmapへの直接の電話ですか?

可能であれば、なぜcallocはしませんか?

+0

優れた 'calloc'実装は、既にゼロであることが知られているOSから得たページをダーティにすることを既に避けています。 http://stackoverflow.com/questions/2688466/why-mallocmemset-is-slower-than-callocを参照してください。アラインメントパラメータをとる 'calloc'のような関数がないように思われるので、あなたは余分なアラインメントを使ってその振る舞いをしたい場合には、自分で行う必要があります。 –

答えて

3

オペレーティングシステムから事前にゼロ化されたメモリを取得するには、いくつかのメカニズムがあります。

mmap(2)MAP_ANONYMOUSフラグはゼロに初期化される内容を強制します。

POSIXがゼロ

  • shm_open(3)また、メモリ・セグメントを可能な共有は、あなたのアドレス空間にしたいサイズに「ファイル」
  • mmap(2)「ファイル」
  • ftruncate(2)ファイルディスクリプタを提供します

メモリは事前にゼロに来ます

This volume of IEEE Std 1003.1-2001 specifies that memory 
    objects have initial contents of zero when created. This is 
    consistent with current behavior for both files and newly 
    allocated memory. For those implementations that use physical 
    memory, it would be possible that such implementations could 
    simply use available memory and give it to the process 
    uninitialized. This, however, is not consistent with standard 
    behavior for the uninitialized data area, the stack, and of 
    course, files. Finally, it is highly desirable to set the 
    allocated memory to zero for security reasons. Thus, 
    initializing memory objects to zero is required. 

なお、このメモリは、使用にゼロにされると思われる:mm/shmem.c機能shmem_zero_setup()

/** 
* shmem_zero_setup - setup a shared anonymous mapping 
* @vma: the vma to be mmapped is prepared by do_mmap_pgoff 
*/  
int shmem_zero_setup(struct vm_area_struct *vma) 
{ 
    struct file *file; 
    loff_t size = vma->vm_end - vma->vm_start; 

    file = shmem_file_setup("dev/zero", size, vma->vm_flags); 
    if (IS_ERR(file)) 
     return PTR_ERR(file); 

    if (vma->vm_file) 
     fput(vma->vm_file); 
    vma->vm_file = file; 
    vma->vm_ops = &shmem_vm_ops; 
    return 0; 
} 
3

あなたはmalloc関数ではcallocをエミュレートしようとしている場合は(つまりmalloc関数を使用しますが、ゼロメモリを受け取る)、あなたはmemsetでそうすることができます。

foo = (char*)malloc(BLOCK_SIZE); 
memset(foo,'\0',BLOCK_SIZE); 

をしかし、これは悪い考えである(それは遅くなりますあなたはFritschy's answerに記載されている理由により、あなたが参照する「遅延割り当て」にはなりません。

+0

malloc + memsetとcallocのパフォーマンスにリンクしてくれてありがとうございました – MofX

+0

Glibcの 'calloc'は、' mmap'がすでにメモリをゼロにしていることを知っていますので、 'calloc'は常に0を書き込む違う。しかし幸いにも、gccはmalloc + memsetを可能な限り 'calloc'に最適化します。 –

0

callocは、あなたが言うように、割り当てられたメモリをゼロにし、さらに2つのパラメータ - (NumberOfElements, ElementSize)を受け入れることを除いて、mallocと同じです。そう

malloc(size); 

は、後者がゼロメモリを提供することを除いて

calloc(1, size); 

と等価です。

これは、「オンデマンドで」あなたが話すメモリをどのように割り当てるのでしょうか?

0

calloc概念的メモリゾーンのゼロING続いmallocと同じです。

なぜ私はmallocがやっていると信じていません怠け者割り振り。それはしません。

いくつかのLinuxシステムにはmemory overcommitが含まれていましたが、それに頼るべきではありません(IMHOという機能よりも設計上のバグです)。また、calloc大きなメモリゾーンは、通常、そのゾーンの追加のクリアを必要としないmmapへの呼び出しによって実装されます。

怠け者が必要な場合は、mmapMAP_NORESERVEを使用することがありますが、それには注意してください。

+1

glibcの 'calloc'は' mmap'からのメモリがすでにゼロになっていることを知っています。 'calloc'で大量の割り当てを行っても、システムがスワップすることはありません。なぜなら、ページをダーティにしないからです。 gccは 'mmap' +' memset'を 'calloc'に最適化します。 (関連:なぜ 'aligned_calloc'が生のmmap以外にもなく、' free'に渡すことのできないポインタを生成します) –

0

Linuxでは(おそらく他のOSでも可能ですが)、あなたが割り当てているのは仮想アドレス空間で実際のアドレス空間ではありません。その仮想アドレス空間を読み書きする場合、カーネルは使用可能なメモリページを見つけて、その仮想アドレス空間にマップします(スワップまたは揮発性メモリの可能性があります)。 htopのようなツールを実行すると、いくつかのメモリ統計が表示されます。ここで見るべき大きなものは、常駐メモリと仮想メモリです。常駐メモリとは、プロセスが実際にどのくらいのメモリを使用しているかということで、仮想メモリは要求されたすべてのメモリの合計です。

callocを呼び出すと、mallocと同じようにメモリを割り当てます。その後、アドレス空間全体にゼロを書き込むことになります。これらの書き込みによって、カーネルは実際のアドレス空間を割り当て、それを仮想アドレス空間にマッピングします。

これを念頭に置いて、malloc自体は怠惰ではなく、カーネルが怠け者であり、必要になるまで実際にメモリページをプロセスに割り当てていません。

一般にメモリがゼロになっている必要がある場合は、callocのようなものを使用してゼロにするか、メモリのチャンクを自分でゼロにしておく必要があります。

関連する問題