一个变量占用多少内存?

How much memory does a variable take?

变量 "a=b" 包含 1 个字符 'a' 作为名称,1 个字符 'b' 作为值。

总共2个字节。

How many characters can you store with one byte ?

变量需要一个指针。 8 个字节。

How many bytes do pointers take up ?

一共10个字节。

存储在内存中的变量"a=b"是否占用大约10个字节? 10 个相同大小的变量会占用大约 100 个字节吗?

那么 1000 个 1000 字节的变量将近 1MB 内存?

我有一个只包含变量的文件 data.sh。 我需要检索该文件中一个变量的值。 我通过使用一个函数来做到这一点。 (由“'function-name' 'datafile-name' 'variable-name'”调用)

#!/usr/pkg/bin/ksh93

readvar () {
    while read -r line
    do
            typeset "${line}"
    done < ""

    nameref indirect=""
    echo "${indirect}"
 }

readvar datafile variable

函数逐行读取文件data.sh。 虽然这样做是排版每一行。 完成之后, 它从函数调用中的变量名进行名称引用, 到文件 data.sh 的变量之一。 最终打印该变量的值。

函数完成后,它不再占用内存。 但只要函数是 运行 就可以。

这意味着文件 data.sh 中的所有变量都在某个时刻存储在内存中。

正确吗?

实际上我有一个文件,其中 ip 地址作为变量名,昵称作为值。所以我想这不会是内存上的问题。但是,如果我也将此用于 posts 的访问者变量值将更大。但是这样就可以让这个函数每次只在内存中存储例如 10 个变量。 但是我想知道我计算变量的这种内存使用情况的方法是否有意义。

编辑:

这可能是避免将整个文件加载到内存中的解决方案。

#!/bin/ksh

readvar () {
input=$(print "" | sed 's/\[/\[/g' | sed 's/\]/\]/g')
line=$(grep "${input}" "")
typeset ${line}
nameref indirect=""
print "${indirect}"
}

readvar ./test.txt input[0]

随着输入test.txt

input[0]=192.0.0.1
input[1]=192.0.0.2
input[2]=192.0.0.2

和输出

192.0.0.1

编辑:

当然有!!! 原来post Bash read array from an external file 它说:

# you could do some validation here

所以:

    while read -r line
do
    # you could do some validation here
    declare "$line"
done < ""

行将在条件下声明(或在 ksh 中排版)。

您真正关心的似乎不是"how much memory does this take?",而是"how can I avoid taking uselessly much memory for this?"。我先回答这个问题。关于原问题的一堆想法,请看我回答的结尾。

为了避免耗尽内存,我建议使用 grep 获取您感兴趣的一行并忽略所有其他行:

line=$(grep "^=" "")

然后您可以从这一行中提取您需要的信息:

result=$(echo "$line" | cut -d= -f 2)

现在变量 result 包含在文件 </code> 中分配给 <code> 的值。由于您不需要存储多个这样的结果值,因此您肯定没有内存问题。

现在,回到原来的问题:

要找出每个变量 shell 使用了多少内存是很棘手的。您需要查看 shell 的来源以确保实现。它可以从 shell 到 shell 不等(您似乎使用的是 ksh,这在这方面可能与 bash 不同)。它也可能因版本而异。

获得想法的一种方法是观察 shell 进程的内存使用情况,同时使 shell 设置大量变量:

bash -c 'a="$(head -c 1000 /dev/zero | tr "[=12=]" x)"; for ((i=0; i<1000; i++)); do eval a${i}="$a"; done; grep ^VmPeak /proc/$$/status'
bash -c 'a="$(head -c 1000 /dev/zero | tr "[=12=]" x)"; for ((i=0; i<10000; i++)); do eval a${i}="$a"; done; grep ^VmPeak /proc/$$/status'
bash -c 'a="$(head -c 1000 /dev/zero | tr "[=12=]" x)"; for ((i=0; i<100000; i++)); do eval a${i}="$a"; done; grep ^VmPeak /proc/$$/status'
bash -c 'a="$(head -c 1000 /dev/zero | tr "[=12=]" x)"; for ((i=0; i<200000; i++)); do eval a${i}="$a"; done; grep ^VmPeak /proc/$$/status'

这会打印 bash 使用的内存峰值,它设置 1000、10000、100000 和 200000 个变量,值为 1000 x 个字符。在我的机器上(使用 bash 4.2.25(1)-release)这给出了以下输出:

VmPeak:    19308 kB
VmPeak:    30220 kB
VmPeak:   138888 kB
VmPeak:   259688 kB

这表明使用的内存或多或少以线性方式增长(加上 ~17000k 的固定偏移量)并且每个新变量占用~1.2kB 的额外内存。

但正如我所说,其他 shell 的结果可能会有所不同。