我的计划是 "Killed"
My program was "Killed"
可能是内核建议的 question。我想看看我为什么会被杀,比如暗杀事件发生的原因。 :)
另外,有什么办法可以让我的程序正常执行吗?
编年史
我的程序可以正常执行。然而,我们遇到了一个很大的数据集,1.000.000 x 960 浮点数,我家里的笔记本电脑无法接受它(给了一个std::bad_alloc()
)。
现在,我在实验室里,在 9.8 GiB 的台式机上,处理器为 3.00GHz × 4,其内存是家里笔记本电脑的两倍多。
在家里,无法将数据集加载到存储数据的std::vector
。在这里,在实验室中,这已经完成,程序继续构建数据结构。
那是我最后一次听到它的消息:
Start building...
Killed
实验室中的桌面在 Debian 8 上运行。对于数据集的一个子集,我的程序按预期运行,特别是 1.00.000 x 960 浮点数。
编辑
strace
输出终于可用了:
...
brk..
brk(0x352435000) = 0x352414000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f09c1563000
munmap(0x7f09c1563000, 44683264) = 0
munmap(0x7f09c8000000, 22425600) = 0
mprotect(0x7f09c4000000, 135168, PROT_READ|PROT_WRITE) = 0
...
mprotect(0x7f09c6360000, 8003584, PROT_READ|PROT_WRITE) = 0
+++ killed by SIGKILL +++
所以这告诉我们我失忆了,我猜测。
例如首先安装信号处理器
static bool installSignalHandler(int sigNumber, void (*handler)(int) = signal_handler)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = signal_handler_action;
return !sigaction(sigNumber, &action, NULL);
}
称之为:
installSignalHandler(SIGINT);
installSignalHandler(SIGTERM);
然后将执行下一段代码:
static void signal_handler_action(int sig, siginfo_t *siginfo, void* content)
{
switch(sig) {
case SIGHUP:
break;
case SIGUSR1:
break;
case SIGTERM:
break;
case SIGINT:
break;
case SIGPIPE:
return;
}
}
查看所需数据的siginfo_t
结构
printf("Continue. Signo: %d - code: %d - value: %d - errno: %d - pid: %ld - uid: %ld - addr %p - status %d - band %d",
siginfo->si_signo, siginfo->si_code, siginfo->si_value, siginfo->si_errno, siginfo->si_pid, siginfo->si_uid, siginfo->si_addr,
siginfo->si_status, siginfo->si_band);
在 C++ 中,浮点数是单个(32 位)浮点数:
http://en.wikipedia.org/wiki/Single-precision_floating-point_format
这意味着您正在分配(无开销)3 840 000 000 bytes 数据。
或大约 3,57627869 GB..
让我们安全地假设向量的 header 与数据相比毫无意义,并继续使用这个数字..
要建立的数据量很大,Linux 可能会认为这只是内存泄漏,并通过终止应用程序来自我保护:
我不认为这是一个过度使用的问题,因为您实际上在单个应用程序中使用了将近一半的内存。
但也许..考虑这只是为了好玩..您正在构建 32 位应用程序吗?
如果它是 32 位构建,你正在接近 2^32 (4Gb) 内存 space 可以被你的程序寻址..
因此,如果您分配了另一个大向量... bum bum bum
可能是内核建议的 question。我想看看我为什么会被杀,比如暗杀事件发生的原因。 :)
另外,有什么办法可以让我的程序正常执行吗?
编年史
我的程序可以正常执行。然而,我们遇到了一个很大的数据集,1.000.000 x 960 浮点数,我家里的笔记本电脑无法接受它(给了一个std::bad_alloc()
)。
现在,我在实验室里,在 9.8 GiB 的台式机上,处理器为 3.00GHz × 4,其内存是家里笔记本电脑的两倍多。
在家里,无法将数据集加载到存储数据的std::vector
。在这里,在实验室中,这已经完成,程序继续构建数据结构。
那是我最后一次听到它的消息:
Start building...
Killed
实验室中的桌面在 Debian 8 上运行。对于数据集的一个子集,我的程序按预期运行,特别是 1.00.000 x 960 浮点数。
编辑
strace
输出终于可用了:
...
brk..
brk(0x352435000) = 0x352414000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f09c1563000
munmap(0x7f09c1563000, 44683264) = 0
munmap(0x7f09c8000000, 22425600) = 0
mprotect(0x7f09c4000000, 135168, PROT_READ|PROT_WRITE) = 0
...
mprotect(0x7f09c6360000, 8003584, PROT_READ|PROT_WRITE) = 0
+++ killed by SIGKILL +++
所以这告诉我们我失忆了,我猜测。
例如首先安装信号处理器
static bool installSignalHandler(int sigNumber, void (*handler)(int) = signal_handler)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = signal_handler_action;
return !sigaction(sigNumber, &action, NULL);
}
称之为:
installSignalHandler(SIGINT);
installSignalHandler(SIGTERM);
然后将执行下一段代码:
static void signal_handler_action(int sig, siginfo_t *siginfo, void* content)
{
switch(sig) {
case SIGHUP:
break;
case SIGUSR1:
break;
case SIGTERM:
break;
case SIGINT:
break;
case SIGPIPE:
return;
}
}
查看所需数据的siginfo_t
结构
printf("Continue. Signo: %d - code: %d - value: %d - errno: %d - pid: %ld - uid: %ld - addr %p - status %d - band %d",
siginfo->si_signo, siginfo->si_code, siginfo->si_value, siginfo->si_errno, siginfo->si_pid, siginfo->si_uid, siginfo->si_addr,
siginfo->si_status, siginfo->si_band);
在 C++ 中,浮点数是单个(32 位)浮点数: http://en.wikipedia.org/wiki/Single-precision_floating-point_format
这意味着您正在分配(无开销)3 840 000 000 bytes 数据。
或大约 3,57627869 GB..
让我们安全地假设向量的 header 与数据相比毫无意义,并继续使用这个数字..
要建立的数据量很大,Linux 可能会认为这只是内存泄漏,并通过终止应用程序来自我保护:
我不认为这是一个过度使用的问题,因为您实际上在单个应用程序中使用了将近一半的内存。
但也许..考虑这只是为了好玩..您正在构建 32 位应用程序吗? 如果它是 32 位构建,你正在接近 2^32 (4Gb) 内存 space 可以被你的程序寻址..
因此,如果您分配了另一个大向量... bum bum bum