bash:简单和大数组上的巨大循环,最后一个元素 内存泄漏的错误



在一系列字符串的最后一个元素上,脚本悬挂,使用100%的CPU,内存获得超过500MB,以及更多....

阵列大小为1406
bash是4.3(旧服务器(
有人知道这个错误吗?

# get sorted values (strings) of the associative array to build a simple array
final=($(for k in "${!namefiles_servers[@]}"; do echo $k===${namefiles_servers[$k]}; done | sort))
for val in "${final[@]}"; do
... 
# at the 1406th element, the last statement of the loop is executed and the script hangs
done

我们需要有关您的问题的更多信息,最好是问题发生的整个脚本部分。我们需要知道您在循环中在做什么,因为它可能是由某些程序引起的。

但是,以下是有关加速脚本的一些信息。如果它与过多的资源有关,则可以轻松优化脚本。

对于大问题,当然,当您使用慢速(但被爱(语言作为bash时,将数据存储在文件中比将它们全部用于循环时更好。这是因为For Loop保留了整个数组,而使用下面的代码逐线解析。当然,如果您有单独的数据块,则需要使用读取其-d选项或其他内容来界定它。

# sort your file here
while read -r line; do
    #something
done < ${MYIFLE}

可能引起问题的另一件事是将整个数组提供给功能,例如:

function test_array_1 {
        local arr=($@)
        sleep 1
        (for i in ${arr[@]}; do echo $i; done)>/dev/null
}

最好将其引用,因为它会忽略副本。这使脚本更快。

function test_array_2 {
        local -n arr=$1
        sleep 1
        (for i in ${arr[@]}; do echo $i; done)>/dev/null
}

副本将在下面的脚本下大约3分钟,而参考需要44秒。您可以自己测试。

#! /bin/bash
function test_array_1 {
        local arr=($@)
        sleep 1
        (for i in ${arr[@]}; do echo $i; done)>/dev/null
}
function test_array_2 {
        local -n arr=$1
        sleep 1
        (for i in ${arr[@]}; do echo $i; done)>/dev/null
}
test_function=$1
ARR=$(seq 1 10000000)
if [ "${test_function}" = "test_array_1" ]; then 
        time test_array_1 ${ARR[@]} &
elif [ "${test_function}" = "test_array_2" ]; then
        time test_array_2 ARR &
fi
wait
exit 0

编辑:
考虑更多,为什么需要两个阵列?由于阵列的条目量相等,因此您可以重写循环并使final数组冗余。

#! /bin/bash
# This array represents random data, which you seem to have. Otherwise, don't 
# sort at all 
namefiles_servers=("$(seq 1 100 | sort -R)")
# You can sort it as such, no need for loops.
namefiles_servers=($(echo "${namefiles_servers[@]}" | sort))
# And access it with a loop. ${#namefiles_servers[@]} is the number of 
# elements in your array
for ((i=0; i<${#namefiles_servers[@]}; i++)); do
        echo index $i has value ${namefiles_servers[$i]}
done

最新更新