变量需要多少内存?

时间:2017-03-27 08:44:45

标签: bash variables memory ksh

变量"a=b"包含名称的1个char 'a'和值的1个char '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。 我需要检索该文件中一个变量的值。 我通过使用一个函数来做到这一点。 (通过"'功能名称''数据文件名''变量名'")

#!/usr/pkg/bin/ksh93

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

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

readvar datafile variable

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

当功能完成时,它不再耗尽内存。 但只要函数正在运行它就可以了。

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

正确吗?

实际上我有一个文件,其中ip-addresses是变量名,昵称是值。所以我想这不会是内存上的问题。但是如果我也将它用于访问者的帖子,变量值将会更大。但是这样就可以让这个函数每次只在内存中存储10个变量。 但是我想知道我计算变量的内存使用量的方式是否有意义。

编辑:

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

#!/bin/ksh

readvar () {
input=$(print "${2}" | sed 's/\[/\\[/g' | sed 's/\]/\\]/g')
line=$(grep "${input}" "${1}")
typeset ${line}
nameref indirect="${2}"
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

编辑:

当然!!! 在原帖中 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 < "$1"
在条件下,

行将被声明(或在ksh中排版)。

1 个答案:

答案 0 :(得分:2)

你真正的担忧似乎不是&#34;这需要多少内存?&#34;但是&#34;我怎么能避免为此花费无用的记忆?&#34;。我先回答这个问题。关于原始问题的一堆想法,请参阅我的答案的结尾。

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

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

然后,您可以从此行中提取所需的信息:

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

现在,变量result包含已分配给文件$2中的$1的值。由于您不需要存储多个此类结果值,因此您肯定没有内存问题。

现在,问到原来的问题:

要了解shell用于每个变量的内存量是多么棘手。您需要查看shell的源代码以确保实现。它可能因shell而异(您似乎使用ksh,在这方面可能与bash不同)。它也可能因版本而异。

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

bash -c 'a="$(head -c 1000 /dev/zero | tr "\0" 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 "\0" 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 "\0" 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 "\0" 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的额外内存。

但正如我所说,其他贝壳&#39;结果可能会有所不同。