2017-03-27 6 views
1

Die Variable "a=b" enthält 1 Char 'a' für den Namen und 1 Char 'b' für den Wert.Wie viel Speicher benötigt eine Variable?

Zusammen 2 Bytes.

How many characters can you store with one byte ?

Die Variable muss einen Zeiger. 8 Bytes.

How many bytes do pointers take up ?

zusammen 10 Bytes.

Nimmt eine Variable "a=b", die im Speicher gespeichert ist, ungefähr 10 Bytes an? Und würden 10 Variablen der gleichen Größe etwa 100 Bytes benötigen?

Also 1000 Variablen von 1000 Bytes jeder wäre fast 1 MB Speicher?

Ich habe eine Datei data.sh, die nur Variablen enthält. Ich muss den Wert einer Variablen in dieser Datei abrufen. Ich mache das mit einer Funktion. (durch " 'function-name' 'Daten-Datei-Namen' 'Variablenname'" genannt)

#!/usr/pkg/bin/ksh93 

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

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

readvar datafile variable 

Die Funktion liest die Datei data.sh Zeile für Zeile. Während dies geschieht, wird jede Zeile typisiert. Danach ist eine Namensreferenz von der Variable-Name im Funktionsaufruf zu einer der Variablen der Datei data.sh. Um schließlich den Wert dieser Variablen zu drucken.

Wenn die Funktion beendet ist, verbraucht sie keinen Speicher mehr. Aber so lange die Funktion läuft, tut es das.

Das bedeutet, dass alle Variablen in der Datei data.sh irgendwann im Speicher gespeichert sind.

Korrekt?

In Wirklichkeit habe ich eine Datei mit IP-Adressen als Variablenname und einen Kurznamen als Werte. Ich nehme an, dass dies kein Problem für die Erinnerung sein wird. Aber wenn ich dies auch für Besucherbeiträge verwende, werden variable Werte größer sein. Aber dann wäre es möglich, dass diese Funktion immer nur 10 Variablen im Speicher speichert. Allerdings frage ich mich, ob meine Art der Berechnung dieser Speichernutzung von Variablen sinnvoll ist.

Edit:

Dies könnte eine Lösung sein, zu vermeiden, dass die gesamte Datei in den Speicher zu laden.

#!/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] 

Mit dem Eingang test.txt

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

und der Ausgang

192.0.0.1 

Edit:

Natürlich !!! In der ursprünglichen Nachricht Bash read array from an external file es:

# you could do some validation here 

so:

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

Linien (oder setzen in KSH) erklärt würden unter einer Bedingung.

Antwort

2

Ihre wirkliche Sorge scheint nicht zu sein "wie viel Speicher dauert das?" aber "wie kann ich vermeiden, nutzlos viel Speicher dafür zu nehmen?". Ich werde das zuerst beantworten. Für ein paar Gedanken über die ursprüngliche Frage, sehen Sie das Ende meiner Antwort.

Zur Vermeidung von Speicher-I grep verwenden vorschlagen verwenden, um die eine Zeile zu erhalten, die für Sie von Interesse ist und alle anderen ignorieren:

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

Dann können Sie die Informationen, die Sie von dieser Linie müssen extrahieren :

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

Nun ist die Variable result enthält den Wert, der $2 in der Datei $1 zugewiesen worden wäre. Da Sie nicht mehr als einen solchen Ergebniswert speichern müssen, haben Sie definitiv kein Speicherproblem.

nun auf die ursprüngliche Frage:

Um herauszufinden, wie viel Speicher eine Schale für jede Variable verbraucht ist schwierig. Sie müssen sich die Quelle der Shell ansehen, um sicher zu sein, dass die Implementierung funktioniert. Es kann von Hülle zu Hülle variieren (Sie scheinen ksh zu verwenden, was in diesem Aspekt von bash abweichen kann). Es kann auch von Version zu Version variieren.

Ein Weg, um eine Vorstellung zu bekommen, wäre ein Shell-Prozesses der Speichernutzung zu beobachten, während des Shell Setvariablen in großen Mengen zu machen:

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' 

Dieser druckt die Spitzenmenge von Speichern in Verwendung durch ein bash die Sets 1000, 10000, 100000 und 200000 Variablen mit einem Wert von 1000 x Zeichen. Auf meinem Rechner (bash 4.2.25 (1) -release mit) ergab dies die folgende Ausgabe:

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

Dies zeigt, dass der Speicher, wächst mehr oder weniger in einer linearen Weise (plus ein fester Offset von ~ 17000k) und jede neue Variable benötigt ~ 1,2kB zusätzlichen Speicher.

Aber wie gesagt, die Ergebnisse anderer Schalen können variieren.

+1

Ok, danke, ich denke, die folgende eine Lösung sein, kann es Ihre Art und Weise zu tun: '#/bin/ksh ReadVar() { Eingang = $ (print "$ {2}" | sed‚s!/\ [/ \\ [/ g '| sed' s/\]/\\]/g ') Zeile = $ (grep "$ {input}" "$ {1}") typeset $ { "$ {} indirekter" } ReadVar ./test.txt Eingang [0] 'mit Eingabedatei line} nameref indirekter = "$ {2}" Druck test.txt' Eingang [0] = 192,0 .0.1' Ausgabe: '192.0.0.1' :) – azbc

Verwandte Themen