变量"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中排版)。
答案 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;结果可能会有所不同。