我尝试在 R 中使用大约 7.6 GB 的大块内存。我的系统有 16 GB 的 RAM,所以我没想到这会是个问题。然而,R 阻止了这种情况,试图绕过它会导致 R 和各种其他应用程序(Web 浏览器)大量崩溃。系统报告了总线问题,但我没有确切的错误消息,因为系统最终崩溃了。
我的问题是:发生了什么?如何防止这种情况并在 R (或任何应用程序) 中分配更多内存?
我感觉这可能与可寻址的内存量有关,而不是理论上可用的内存量。
细节
我尝试在 R 中使用更大的内存块,即具有 10 亿个条目的矩阵,大约 7.6 GB。R 无法轻易允许这种大小的向量/矩阵,尽管我不清楚为什么。(结果是Error: cannot allocate vector of size 7.6 Gb
)但是,R 有 bigmemory 等库,据说可以处理大型向量。来自 R 解释器:
> library(bigmemory)
Loading required package: bigmemory.sri
> bx <- big.matrix(45070,45070)
*** caught bus error ***
address 0x7ff75ffac000, cause 'non-existent physical address'
Traceback:
1: .Call("bigmemory_CreateSharedMatrix", PACKAGE = "bigmemory", row, col, colnames, rownames, typeLength, ini, separated)
2: CreateSharedMatrix(as.double(nrow), as.double(ncol), as.character(colnames), as.character(rownames), as.integer(typeVal), as.double(init), as.logical(separated))
3: big.matrix(45070, 45070)
Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
Selection:
因此 R 崩溃了,但可以通过选择 2 并取消退出来挽救。再次尝试同样的做法可能不太明智,但无论如何,我们开始吧:
Selection: 2
Save workspace image? [y/n/c]: c
> bx <- big.matrix(45070,45070)
terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
what(): No space left on device
Aborted (core dumped)
从日志来看,它看起来像这样:
Aug 23 14:49:25 system systemd-coredump[426]: Process 423 (R) of user 1000 dumped core.
Stack trace of thread 423:
#0 0x00007ff94bab18c0 raise (libc.so.6)
#1 0x00007ff94bab2f72 abort (libc.so.6)
#2 0x00007ff94774d035 _ZN9__gnu_cxx27__verbose_terminate_handlerEv (libstdc++.so.6)
#3 0x00007ff94774ac46 _ZN10__cxxabiv111__terminateEPFvvE (libstdc++.so.6)
#4 0x00007ff947749b49 __cxa_call_terminate (libstdc++.so.6)
#5 0x00007ff94774a538 __gxx_personality_v0 (libstdc++.so.6)
#6 0x00007ff9474b3ee3 _Unwind_RaiseException_Phase2 (libgcc_s.so.1)
#7 0x00007ff9474b470e _Unwind_Resume (libgcc_s.so.1)
#8 0x00007ff945279da6 _ZN21SharedMemoryBigMatrix7destroyEv (bigmemory.so)
#9 0x00007ff9452a7762 _Z15CreateRAMMatrixI21SharedMemoryBigMatrixEP7SEXPRECS2_S2_S2_S2_S2_S2_S2_ (bigmemory.so)
#10 0x00007ff94528d79c bigmemory_CreateSharedMatrix (bigmemory.so)
#11 0x00007ff94c11a33a n/a (libR.so)
#12 0x00007ff94c11a8c6 n/a (libR.so)
#13 0x00007ff94c158fb8 Rf_eval (libR.so)
#14 0x00007ff94c15ba3b n/a (libR.so)
#15 0x00007ff94c158d5b Rf_eval (libR.so)
#16 0x00007ff94c15adce n/a (libR.so)
#17 0x00007ff94c150963 n/a (libR.so)
#18 0x00007ff94c158938 Rf_eval (libR.so)
#19 0x00007ff94c15adce n/a (libR.so)
#20 0x00007ff94c158b02 Rf_eval (libR.so)
#21 0x00007ff94c15cbc7 n/a (libR.so)
#22 0x00007ff94c158d5b Rf_eval (libR.so)
#23 0x00007ff94c181f92 Rf_ReplIteration (libR.so)
#24 0x00007ff94c1823b1 n/a (libR.so)
#25 0x00007ff94c182468 run_Rmainloop (libR.so)
#26 0x000000000040074b main (R)
#27 0x00007ff94ba9e4ca __libc_start_main (libc.so.6)
#28 0x000000000040078a _start (R)
-- Subject: Process 423 (R) dumped core
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- Documentation: man:core(5)
--
-- Process 423 (R) crashed and dumped core.
--
-- This usually indicates a programming error in the crashing program and
-- should be reported to its vendor as a bug.
全系统后果
此时,桌面环境和图形应用程序均未运行。我启动了窗口管理器和浏览器来查看发生了什么。令我惊恐的是,我发现 Firefox、Opera 或 Chromium 都无法启动。错误消息提到了总线错误,但由于系统最终崩溃,我没有确切的错误消息。值得注意的是,其他应用程序,甚至更大的应用程序,例如 libreoffice,都可以毫无问题地启动。这可能与建立网络连接所需的地址有关吗?可能是 R 崩溃后系统不知何故没有地址了?(但是,我不明白为什么在 R 进程终止后这种情况会持续存在。)
从日志来看,它看起来像这样(长堆栈跟踪被截断):
Aug 23 15:16:19 system systemd-coredump[18050]: Process 18017 (firefox) of user 1000 dumped core.
Stack trace of thread 18017:
#0 0x00007ff72e679018 sem_init@@GLIBC_2.2.5 (libpthread.so.0)
(...)
Aug 23 15:16:20 system systemd-coredump[18097]: Process 18062 (firefox) of user 1000 dumped core.
Stack trace of thread 18062:
#0 0x00007f2098a98018 sem_init@@GLIBC_2.2.5 (libpthread.so.0)
(...)
Aug 23 15:16:21 system systemd-coredump[18144]: Process 18109 (firefox) of user 1000 dumped core.
Stack trace of thread 18109:
#0 0x00007f2d45410018 sem_init@@GLIBC_2.2.5 (libpthread.so.0)
(...)
(...)
(...)
Aug 23 15:19:16 system systemd-coredump[19510]: Process 19370 (opera) of user 1000 dumped core.
Stack trace of thread 19395:
#0 0x0000000001c882f7 n/a (opera)
#1 0x0000000001c890e9 n/a (opera)
(...)
Aug 23 15:20:58 system systemd-coredump[20140]: Process 20136 (evas_image_load) of user 1000 dumped core.
Stack trace of thread 20136:
#0 0x00007fba4432babd __memset_avx2_erms (libc.so.6)
(...)
Aug 23 15:30:11 system systemd-coredump[20990]: Process 20958 (WebKitWebProces) of user 1000 dumped core.
Stack trace of thread 20958:
#0 0x00007fc5dd5ed7d0 n/a (libpixman-1.so.0)
#1 0x00007fc5dd5d273b n/a (libpixman-1.so.0)
(...)
Aug 23 15:31:07 system systemd-coredump[22406]: Process 20936 (midori) of user 1000 dumped core.
Stack trace of thread 22403:
#0 0x00007f3a38d5b6df __memmove_avx_unaligned_erms (libc.so.6)
#1 0x00007f3a39759e78 n/a (libwebkit2gtk-4.0.so.37)
然后我尝试重新启动 dbus(这也不是最明智的举动并导致系统崩溃)。
其他方面
在系统崩溃之前,我还意识到了以下几点:
[user@system ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
dev 7.6G 0 7.6G 0% /dev
run 7.6G 788K 7.6G 1% /run
/dev/mapper/root 412G 89G 324G 22% /
tmpfs 7.6G 7.6G 0 100% /dev/shm
tmpfs 7.6G 0 7.6G 0% /sys/fs/cgroup
/dev/sda1 2.0G 52M 1.8G 3% /boot
tmpfs 7.6G 0 7.6G 0% /tmp
tmpfs 1.6G 0 1.6G 0% /run/user/1000
[user@system ~]$ free -m
total used free shared buff/cache available
Mem: 15469 146 7438 7735 7884 7349
Swap: 14335 0 14335
[user@system ~]$
为什么虚拟文件系统(dev、run、tmpfs)的大小都是 7.6GB,而这正是 R 不会分配的?
我已经验证,在 R 中可以分配多达 6.7GB,但在 7.6GB 以下的某个地方存在限制。R 或系统中未设置最大内存:
[user@system ~]$ ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 61833
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 99
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 61833
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
...在 R 解释器中:
> Sys.getenv("R_MAX_MEM_SIZE")
[1] ""
> Sys.getenv()
COLUMNS 235
DBUS_SESSION_BUS_ADDRESS
unix:path=/run/user/1000/bus
DESKTOP Enlightenment
DISPLAY :0.0
E_BIN_DIR /usr/bin
E_CONF_PROFILE standard
E_DATA_DIR /usr/share/enlightenment
E_ICON_THEME gnome
E_IPC_SOCKET /run/user/1000/e-user@0/633
E_LIB_DIR /usr/lib
E_LOCALE_DIR /usr/share/locale
E_PREFIX /usr
E_RESTART 1
E_SCALE 1.000
E_START enlightenment_start
E_START_TIME 1503499246.8
E_TAINTED NO
EDITOR vi
HOME /home/user
LANG en_GB.UTF-8
LD_LIBRARY_PATH /usr/lib64/R/lib:/usr/lib/jvm/java-7-openjdk/jre/lib/amd64/server
LINES 58
LN_S ln -s
LOGNAME user
M2 /opt/maven//bin
M2_HOME /opt/maven/
MAIL /var/spool/mail/user
MAKE make
MAVEN_OPTS -Xmx512m
MOZ_PLUGIN_PATH /usr/lib/mozilla/plugins
PAGER /usr/bin/less
PANTS ON
PATH /opt/maven//bin:/home/user/Applications/.bin:/usr/bin:/opt/maven//bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
PWD /home/user
QT_QPA_PLATFORMTHEME gtk2
QT_STYLE_OVERRIDE gtk2
R_ARCH
R_BROWSER /usr/bin/xdg-open
R_BZIPCMD /usr/bin/bzip2
R_DOC_DIR /usr/share/doc/R/
R_GZIPCMD /usr/bin/gzip
R_HOME /usr/lib64/R
R_INCLUDE_DIR /usr/include/R/
R_LIBS_SITE
R_LIBS_USER ~/R/x86_64-pc-linux-gnu-library/3.4
R_PAPERSIZE a4
R_PDFVIEWER /usr/bin/xdg-open
R_PLATFORM x86_64-pc-linux-gnu
R_PRINTCMD
R_RD4PDF times,inconsolata,hyper
R_SESSION_TMPDIR /tmp/RtmpXBvepb
R_SHARE_DIR /usr/share/R/
R_SYSTEM_ABI linux,gcc,gxx,gfortran,?
R_TEXI2DVICMD /usr/bin/texi2dvi
R_UNZIPCMD /usr/bin/unzip
R_ZIPCMD /usr/bin/zip
SED /usr/bin/sed
SHELL /bin/bash
SHLVL 3
TAR /usr/bin/tar
TERM xterm
USER user
WINDOWPATH 1
XAUTHORITY /home/user/.Xauthority
XDG_CONFIG_DIRS /usr/etc/xdg:/etc/xdg
XDG_DATA_DIRS /usr/share/enlightenment:/usr/share:/usr/local/share:/usr/share
XDG_MENU_PREFIX e-
XDG_RUNTIME_DIR /run/user/1000
XDG_SEAT seat0
E_PREFIX /usr
E_RESTART 1
E_SCALE 1.000
E_START enlightenment_start
E_START_TIME 1503499246.8
E_TAINTED NO
EDITOR vi
HOME /home/user
LANG en_GB.UTF-8
LD_LIBRARY_PATH /usr/lib64/R/lib:/usr/lib/jvm/java-7-openjdk/jre/lib/amd64/server
LINES 58
LN_S ln -s
LOGNAME user
M2 /opt/maven//bin
M2_HOME /opt/maven/
MAIL /var/spool/mail/user
MAKE make
MAVEN_OPTS -Xmx512m
MOZ_PLUGIN_PATH /usr/lib/mozilla/plugins
PAGER /usr/bin/less
PANTS ON
PATH /opt/maven//bin:/home/user/Applications/.bin:/usr/bin:/opt/maven//bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
PWD /home/user
QT_QPA_PLATFORMTHEME gtk2
QT_STYLE_OVERRIDE gtk2
R_ARCH
R_BROWSER /usr/bin/xdg-open
R_BZIPCMD /usr/bin/bzip2
R_DOC_DIR /usr/share/doc/R/
R_GZIPCMD /usr/bin/gzip
R_HOME /usr/lib64/R
R_INCLUDE_DIR /usr/include/R/
R_LIBS_SITE
R_LIBS_USER ~/R/x86_64-pc-linux-gnu-library/3.4
R_PAPERSIZE a4
R_PDFVIEWER /usr/bin/xdg-open
R_PLATFORM x86_64-pc-linux-gnu
R_PRINTCMD
R_RD4PDF times,inconsolata,hyper
R_SESSION_TMPDIR /tmp/RtmpXBvepb
R_SHARE_DIR /usr/share/R/
R_SYSTEM_ABI linux,gcc,gxx,gfortran,?
R_TEXI2DVICMD /usr/bin/texi2dvi
R_UNZIPCMD /usr/bin/unzip
R_ZIPCMD /usr/bin/zip
SED /usr/bin/sed
SHELL /bin/bash
SHLVL 3
TAR /usr/bin/tar
TERM xterm
USER user
WINDOWPATH 1
XAUTHORITY /home/user/.Xauthority
XDG_CONFIG_DIRS /usr/etc/xdg:/etc/xdg
XDG_DATA_DIRS /usr/share/enlightenment:/usr/share:/usr/local/share:/usr/share
XDG_MENU_PREFIX e-
XDG_RUNTIME_DIR /run/user/1000
XDG_SEAT seat0
XDG_SESSION_ID c1
XDG_VTNR 1
XMODIFIERS @im=ibus
软件
R版本是3.4.1;系统是Arch Linux。
[user@system ~]$ uname -a
Linux system 4.11.9-1-ARCH #1 SMP PREEMPT Wed Jul 5 18:23:08 CEST 2017 x86_64 GNU/Linux
答案1
这是我极少数不同意重力他的回答总能给很多人带来启发,当然也给我带来启发。
原因是/dev/shm是不是由其他进程引起的,因此可以轻松释放以供R包,而是由大记忆模块内部R本身!如此自由/dev/shm就等于杀人R。
bigmemory 软件包手册在第 1 页上指出:
描述:创建、存储、访问和操作海量矩阵。矩阵分配到共享内存,并且可以使用内存映射文件。
这澄清了一个重要的观点:你不能指望通过使用大记忆,只有分配给/dev/shm,通常是可用内存总量的一半。如果要增大或缩小共享内存,修改相关行/etc/fstab然后重新启动。
我们可以放心地假设/dev/shm是由于R。事实上,楼主的帖子明确指出当时没有其他程序在运行,
此时,桌面环境和任何图形应用程序均未运行。
,所以很难想象还有什么(IE, 除了R) 可能会占用如此大块的共享内存。
其实问题的根源也很容易理解。首先,你的矩阵
bx <- 大矩阵(45070,45070)
有45070 x 45070> 20 亿个元素。其次,根据R 手册,
R 没有单精度数据类型。所有实数都以双精度格式存储。
进而
所有 R 平台都需要使用符合 IEC 60559(也称为 IEEE 754)标准的值。
....
在 IEEE 754-2008/IEC60559:2011 中,这被称为“binary64”格式。
和有关 binary64 格式的 Wikipedia 文章明确指出:
双精度浮点格式是一种计算机数字格式,在计算机内存中占用 8 个字节(64 位)。
因此,您的 20 多亿个元素(每个元素占用 8 个字节)将占用超过 160 亿字节的内存,这大约是您的/dev/shm(在哪里大记忆想要存储它们,见上文),有可用。因此崩溃,并出现错误消息:
在抛出“boost::interprocess::interprocess_exception”实例后调用终止 what(): 设备上没有剩余空间
此错误消息来自Boost C++ 库,涉及一类函数:
Boost.Interprocess 提供了一些基本类来创建共享内存对象和文件映射,并将这些可映射的类映射到进程的地址空间。
至于你的系统在R核心转储,很好地解释了重力, 在那里面/dev/shm尚未清理,并且所有使用共享内存的进程(例如,使用动态库的所有进程)都将由于设备空间不足而失败:最简单的选择是重新启动。
你有什么选择?首先,也许你可以安装 32GiB 内存,这将彻底解决你目前的困境。或者,你可以看看你的矩阵是否真的需要这么多元素:例如,对称矩阵只包含非对称矩阵的一半多一点的元素,你只需要放大/dev/shm有一点。或者你正在处理一个稀疏矩阵,它比对称矩阵更容易压缩。
换句话说,您必须查看矩阵的一些细节,并找到适合您具体情况的解决方案。
答案2
tmpfs 文件系统会按需增长,因此您看到的“总大小”只是容量限制– 除非在挂载时另有指定,否则默认限制等于物理内存的 50%。(这并不意味着 tmpfs 被锁定在物理内存中;它能被换出。)
然而,请注意一文件系统,,/dev/shm
报告 7.6 GB用过的(即已填满至极限)。此位置是保存 SHM 段(共享内存 - 一种进程间通信功能)的位置,尽管有时程序也会直接在此创建杂项文件。
SHM 段是持久的;如果程序退出时没有明确删除它们,它们就会保留下来。因此,如果您之前的运行继续设置 SHM 然后崩溃,这很容易填满您一半的 RAM,只留下约 8 GB 给新程序。
(反之亦然,由于默认容量为/dev/shm
物理内存的 50%,所有 SHM 段的总大小限制为 7.6 GB。我怀疑这与此无关 —— 如果程序确实需要那么大的 SHM 段,我会感到非常惊讶。)
要清理 /dev/shm,您可以 a) 重新启动,或者 b)小心使用普通的旧版本删除在那里找到的文件rm
。但首先务必使用lsof
以确保它们未被使用。
或者,使用以下方法提高大小限制:
mount -o remount,size=90% /dev/shm
(顺便说一句,您正在运行一个相当老的 Arch Linux 内核 – 当前版本是 4.12.8,除非您运行 linux-lts。)