我想在Linux机器使用的大页面上分配内存.我看到有两种方法可以做到这一点,使用mmap和madvise.
也就是说,使用MAP_HUGETLB带有mmap调用的标志-
base_ptr_ = mmap(NULL, memory_size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
Run Code Online (Sandbox Code Playgroud)
和呼号的MADV_HUGEPAGE旗帜madvise-
madvise(base_ptr_, memory_size_, MADV_HUGEPAGE);
Run Code Online (Sandbox Code Playgroud)
有人可以解释两者之间的区别吗?
我试图抓住784 MiB的内存.是的,我知道这对32位手机来说很重要,但以下调用在Android 5.0之前有效:
mmap(0, 0x31000000, PROT_NONE, MAP_ANON | MAP_SHARED, -1, 0);
Run Code Online (Sandbox Code Playgroud)
但是,在不同制造商的三种不同设备上,升级到Android 5.0已经打破了这一局面.我假设这是5.0中内存分配功能的一些变化; 也许需要传递不同的标志?
这是logcat中返回的错误消息:
E/libc? mmap fail (pid 9994, tid 10125, size 822083584, flags 0x21, errno 12(Out of memory))
Run Code Online (Sandbox Code Playgroud) 我一直在使用openSUSE 11.2 x86_64上的大型稀疏文件.当我尝试mmap()1TB稀疏文件时,它会因ENOMEM而失败.我原以为64位地址空间足以映射到太字节,但似乎没有.进一步尝试,1GB文件工作正常,但2GB文件(和更大的文件)失败.我猜测可能有某个地方可以进行调整,但广泛的搜索没有任何结果.
这里有一些显示问题的示例代码 - 任何线索?
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char * filename = argv[1];
int fd;
off_t size = 1UL << 40; // 30 == 1GB, 40 == 1TB
fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666);
ftruncate(fd, size);
printf("Created %ld byte sparse file\n", size);
char * buffer = (char *)mmap(NULL, (size_t)size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if ( …Run Code Online (Sandbox Code Playgroud) 我到处寻找答案,但我想我已经达到了我能找到的极限.我的问题似乎与此有点相关:升级到Lollipop后,32位设备上的Android NDK mmap调用被破坏但没有提供答案.
我的问题是我尝试通过mmap调用从文件中存储映射457232384字节.在Android 5.1.1的两个不同的设备(三星Galaxy Note 3和OnePlus One,每个3GB RAM)上,该调用失败,错误12"内存不足".实际上,当我尝试分配超过300MB的内存时,调用失败.313524224字节(299MB)工作,314572800(300MB)不会.
事情是,同样的调用适用于第四台仍在Android 4.4.2上的设备.更奇怪的是,这个调用适用于带有SDK 21(Android 5.0)的Android ARM模拟器.不用说,可以毫无问题地加载相同数量的数据(不是mmap').
dmesg向我报告:
<3>[ 1137.488411] [0:Thread-298: 4267] arch_get_unmapped_area (TASK_SIZE - len < addr) len=457232384 task size=3204448256 pid=4267 do_align=0 addr=3034054656 mmap_base=3069939712
Run Code Online (Sandbox Code Playgroud)
尝试映射文件的函数(来自openfst)如下:
MappedFile* MappedFile::Map(istream* s, const FstReadOptions &opts,
size_t size) {
size_t pos = s->tellg();
if (opts.mode == FstReadOptions::MAP && pos >= 0 &&
pos % kArchAlignment == 0) {
int fd = open(opts.source.c_str(), O_RDONLY);
if (fd != -1) {
int pagesize = getpagesize();
off_t offset = …Run Code Online (Sandbox Code Playgroud) 尝试复制2GB左右大小的文件时,FileChannel.transferFrom(source,0,source.size())提供以下OutOfMemory异常。我了解由于文件较大而导致的内存问题。我们是否可以通过循环处理小块文件来解决问题?
01-22 17:27:03.365: W/System.err(28538): java.io.IOException: mmap failed: ENOMEM (Out of memory)
01-22 17:27:03.375: W/System.err(28538): at java.nio.MemoryBlock.mmap(MemoryBlock.java:119)
01-22 17:27:03.375: W/System.err(28538): at java.nio.FileChannelImpl.map(FileChannelImpl.java:249)
01-22 17:27:03.380: W/System.err(28538): at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:381)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.util.InSyncIOUtils.copyFile(InSyncIOUtils.java:123)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.getFileItemForFile(ProcessUploadTask.java:102)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.processUploads(ProcessUploadTask.java:124)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:53)
01-22 17:27:03.380: W/System.err(28538): at com.druva.inSync.AsyncTasks.ProcessUploadTask.doInBackground(ProcessUploadTask.java:1)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-22 17:27:03.380: W/System.err(28538): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-22 17:27:03.380: W/System.err(28538): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-22 17:27:03.380: W/System.err(28538): at …Run Code Online (Sandbox Code Playgroud) mmap ×5
android ×4
android-ndk ×3
c ×2
linux ×2
memory ×2
filechannel ×1
huge-pages ×1
java ×1
unix ×1