我想跟踪各种程序在特定状态下触摸的内存量.例如,假设我有一个图形程序.当它被最小化时,它可能会使用更少的内存,因为它不会重绘窗口,这需要读取图像和字体并执行大量的库函数.这些对象仍可在内存中访问,但实际上并未使用它们.
类似top的工具是有限使用的,因为它们只是告诉多少内存映射到程序的地址空间,以及它有多少驻留在物理RAM中.同样,泄漏检测器只会告诉内存何时无法访问,而不是仅仅是因为它没有被使用.
是否存在可以以这种方式跟踪活动使用/未使用的内存的现有工具?如果可能的话,我不仅要跟踪堆上的使用情况,还要跟踪存储程序/库代码的内存.
编辑:我想澄清一下:我想知道程序实际读取,写入或执行某个点之后的内存,即一旦达到某个状态.虽然地址空间中的页数和常驻页数是重要的测量值,但这不是我想要的.
我现在正在追求三种方法:
需要对我的C应用程序进行内存分析..
它应该包括占用空间大小和RAM大小......
例如,如果我的应用程序如下所示..
#include <stdio.h>
int global = 10; /* initialized global variable */
int test_code(void)
{
static int i = 100; /* Initialized static variable*/
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
[putta@linux]$ gcc memory-layout.c -c memory-layout
[putta@linux]$ ls -ltrh memory-layout.o
760 Nov 9 18:26 memory-layout
[putta@linux]$ size memory-layout.o
text data bss dec hex filename
67 8 0 75 4b memory-layout.o
Run Code Online (Sandbox Code Playgroud)
那么现在我应该考虑哪些内存用于分析足迹,以及加载程序时的RAM.
以下分析是正确的吗?占用内存= 760(即闪存或硬盘)RAM = 67 + 8 + 0 = 75字节
需要专家建议
我正在尝试构建一个小工具,允许我运行程序并通过Go跟踪内存使用情况.我r.exec = exec.Command(r.Command, r.CommandArgs...)用来运行命令,而run.MemStats用于跟踪内存使用情况(在单独的go例程中):
func monitorRuntime() {
m := &runtime.MemStats{}
f, err := os.Create(fmt.Sprintf("mmem_%s.csv", getFileTimeStamp()))
if err != nil {
panic(err)
}
f.WriteString("Time;Allocated;Total Allocated; System Memory;Num Gc;Heap Allocated;Heap System;Heap Objects;Heap Released;\n")
for {
runtime.ReadMemStats(m)
f.WriteString(fmt.Sprintf("%s;%d;%d;%d;%d;%d;%d;%d;%d;\n", getTimeStamp(), m.Alloc, m.TotalAlloc, m.Sys, m.NumGC, m.HeapAlloc, m.HeapSys, m.HeapObjects, m.HeapReleased))
time.Sleep(5 * time.Second)
}
}
Run Code Online (Sandbox Code Playgroud)
当我用简单的程序测试我的代码时(大约12个小时),我注意到Go不断分配更多的内存: 系统内存 堆分配
我做了一些测试,比如在monitorRuntime()没有任何其他代码的情况下运行函数,或者使用pprof,例如:
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
http.ListenAndServe(":8080", nil)
}
Run Code Online (Sandbox Code Playgroud)
然而,我仍然注意到内存分配就像图中一样持续上升.
如何准确跟踪我想要运行的程序的内存使用情况?我知道我过去使用的一种方法是使用,/proc/$PID/statm但该文件并不存在于每个操作系统(例如Mac OS或Windows)中
考虑流程消耗的内存的策略是什么?例如,我有一个程序,在旧版本中,它对内存的使用不是最理想的,并且它没有在正确的时间发布,这意味着它保留了比它应该的更长的分配.请注意,我并不是说它泄露了.该程序的新版本修改了算法,现在内存在程序的生命周期中更早发布.怎么跟踪这个?想到的一些方法是:编写一个包含libc/libstdc ++的malloc/new替换库,以某种方式使用valgrind来执行它或使用ps对流程使用的内存进行采样并绘制图形?
我正在努力将 linux 引入具有 16 Mb SDRAM 和 64 Mb 闪存的定制 Cortex-M7 板。该平台没有 MMU,没有共享库,没有 FLAT 可执行文件。
我在使用非常简单的 init.d shell 脚本启动 Busybox 系统时遇到问题。通过执行诸如“[”或“printf”之类的简单shell命令,系统就会耗尽内存。事实证明,每次执行这些命令之一时,系统都需要加载 FULL、一个且唯一的 busybox 可执行文件(在我的系统上为 650 Kb)。
所以问题是:如果系统总是要为在busybox 中执行的每个命令都在内存中加载一个巨大的可执行文件,那么这有多方便?我不明白在极快地退出内存的同时节省几兆字节的廉价和丰富的存储空间,但也许我忽略了一些东西。
我的平台是 Busybox 的用例吗?如果没有,是否有任何东西可以方便地在自己的可执行文件上构建 linux 系统实用程序?
提前致谢!
编辑:
根据他们自己的说法,Busybox “在编写时考虑了大小优化和有限的资源”,因此成为嵌入式系统中一种毋庸置疑的事实上的标准。但是他们的声明与 RAM(而非存储)受限系统上的上述问题有何关联?我相信这值得一些澄清。
跟进,系统详情:
内核已经为 XIP 编译,从 64 Mb 外部闪存执行。整个读/写 ext3 根文件系统(包括 busybox 二进制文件)现在驻留在微型 SD 卡上。Busybox 可执行文件使用 FLAT 格式(“bFLT”)并启用加载到 RAM 位,该位似乎在每次运行并发命令时在不同的内存块上导致新的加载,直到它耗尽拟合块。将busybox(整个/bin、/sbin)放在XIP 文件系统上的建议非常棒,它肯定会提高执行速度(当然,这个新文件系统需要驻留在64 Mb 外部闪存上)。我从未尝试过在这样的文件系统上执行“bFLT”(也不知道它是否有效),但我会对此进行研究/测试。
运行以下内容可以显示进程的内存使用情况:
$ ps -C processname -o size
SIZE
3808
Run Code Online (Sandbox Code Playgroud)
有没有办法在不执行ps(或任何外部程序)或阅读的情况下检索此信息/proc?
我正在Linux上运行R(kubuntu trusty).我有一个近400MB的csv文件,主要包含数值:
$ ls -lah combined_df.csv
-rw-rw-r-- 1 naught101 naught101 397M Jun 10 15:25 combined_df.csv
Run Code Online (Sandbox Code Playgroud)
我启动R,df <- read.csv('combined_df.csv')(我得到一个1246536x25数据帧,3个int列,3个logi,1个因子和18个数字),然后使用此处的脚本来检查内存使用情况:
R> .ls.objects()
Type Size Rows Columns
df data.frame 231.4 1246536 25
Run Code Online (Sandbox Code Playgroud)
奇怪的是,它报告的内存较少,但我想这只是因为CSV不是数字数据的有效存储方法.
但是当我检查系统内存使用情况时,top说R使用了我可用的8GB内存的20%.并ps报告类似:
$ ps aux|grep R
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
naught1+ 32364 5.6 20.4 1738664 1656184 pts/1 S+ 09:47 2:42 /usr/lib/R/bin/exec/R
Run Code Online (Sandbox Code Playgroud)
用于379MB数据集的1.7Gb RAM.这似乎过分了.我知道这ps不一定是衡量内存使用情况的准确方法,但肯定不会超过5倍?!为什么R使用这么多内存?
此外,R似乎在gc()输出中报告类似的东西:
R> gc()
used (Mb) gc …Run Code Online (Sandbox Code Playgroud) 以下命令行可用于分配任意数量的内存,例如 1GB。内存区域被零填充。
</dev/zero head -c $((1024**3)) | tail
Run Code Online (Sandbox Code Playgroud)
然而,如何用随机数类似地填充给定数量的内存,例如 1GB?
与预期相反,以下两个变体不会导致工作内存的可选择分配大小,而是在终端中输出数百个随机字符:
</dev/random head -c $((1024**3)) | tail
Run Code Online (Sandbox Code Playgroud)
下面的看起来不像是一个解决方案,因为它操作数据(remove/0)并且只保存了几百个字符的变量,而不是1GB:
output=$(sudo head -c $((1024**3)) /dev/random | tr -d '\0' | tail)
Run Code Online (Sandbox Code Playgroud)
关于以下可能是一种解决方案的想法,但看起来 var 上只有几百个字符而不是 1GB:
output=""
while IFS= read -r -d '' substring; do
output+="$substring"
done < <(sudo head -c $((1024**3)) /dev/random | tail)
Run Code Online (Sandbox Code Playgroud) 就我而言,它是"rsyslogd",
我发现它耗费高达170M的内存,这太多了,
我已经检查了位于/etc/rsyslog.conf的配置文件
然后检查里面写的每个文件,
但是徒劳无功
如何查找当前正在操作的文件并查看正在进行的操作?
[root@slvdb2 log]# lsof -p `pidof rsyslogd`
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
rsyslogd 1965 root cwd DIR 8,1 4096 2 /
rsyslogd 1965 root rtd DIR 8,1 4096 2 /
rsyslogd 1965 root txt REG 8,1 259072 2818209 /sbin/rsyslogd
rsyslogd 1965 root mem REG 8,1 142176 1097807 /lib64/ld-2.8.so
rsyslogd 1965 root mem REG 8,1 1804136 1097817 /lib64/libc-2.8.so
rsyslogd 1965 root mem REG 8,1 143096 1097871 /lib64/libpthread-2.8.so
rsyslogd 1965 root mem REG …Run Code Online (Sandbox Code Playgroud) 将值分配给大型数组时,即使没有分配新内存,使用的内存也会不断增加.我只是通过任务管理器(Windows)或系统监视器(Ubuntu)来检查已用内存.
两个操作系统的问题都是一样的.我分别使用gcc 4.7或4.6.
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i,j;
int n=40000000; //array size
int s=100;
double *array;
array=malloc(n*sizeof(double)); //allocate array
if(array==NULL){
return -1;
}
for(i=0;i<n;i++){ //loop for array, memory increases during this loop
for(j=0;j<s;j++){ //loop to slow down the program
array[i] = 3.0;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我没有看到任何逻辑问题,但据我所知,我也没有超出任何系统限制.所以我的问题是:
他人可以重现这个问题吗?
记忆力增长的原因是什么?
我该如何解决这个问题?