私は当初考えていたことをかなり簡単にしようとしています。image.png.Decode()への繰り返し呼び出しによりメモリ不足エラーが発生する
入力ファイルのリスト内のすべてのファイルの場合:
- が
- が、それは「グレーかどうかを確認するために、ファイルやテスト内のすべてのピクセルをスキャンpng.Decode()でファイルを開きウィットに"
- イメージの「グレー」ピクセルの割合を返します。
この私が呼び出しています関数です。
func greyLevel(fname string) (float64, string) {
f, err := os.Open(fname)
if err != nil {
return -1.0, "can't open file"
}
defer f.Close()
i, err := png.Decode(f)
if err != nil {
return -1.0, "unable to decode"
}
bounds := i.Bounds()
var lo uint32 = 122 // Low grey RGB value.
var hi uint32 = 134 // High grey RGB value.
var gpix float64 // Grey pixel count.
var opix float64 // Other (non-grey) pixel count.
var tpix float64 // Total pixels.
for x := bounds.Min.X; x < bounds.Max.X; x++ {
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
r, g, b, _ := i.At(x, y).RGBA()
if ((r/255)-1 > lo && (r/255)-1 < hi) &&
((g/255)-1 > lo && (g/255)-1 < hi) &&
((b/255)-1 > lo && (b/255)-1 < hi) {
gpix++
} else {
opix++
}
tpix++
}
}
return (gpix/tpix) * 100, ""
}
func main() {
srcDir := flag.String("s", "", "Directory containing image files.")
threshold := flag.Float64("t", 65.0, "Threshold (in percent) of grey pixels.")
flag.Parse()
dirlist, direrr := ioutil.ReadDir(*srcDir)
if direrr != nil {
log.Fatalf("Error reading %s: %s\n", *srcDir, direrr)
}
for f := range dirlist {
src := path.Join(*srcDir, dirlist[f].Name())
level, msg := greyLevel(src)
if msg != "" {
log.Printf("error processing %s: %s\n", src, msg)
continue
}
if level >= *threshold {
log.Printf("%s is grey (%2.2f%%)\n", src, level)
} else {
log.Printf("%s is not grey (%2.2f%%)\n", src, level)
}
}
}
ファイルが比較的小さい(960x720、8ビットRGB)
私はリストを生成するために)(ioutil.ReadDirを呼び出していますスライスをループしてgreyLevel()を呼び出します。
した後で(> 4000のリストのうち)スクリプトパニック約155のファイル:
runtime: memory allocated by OS not in usable range
runtime: out of memory: cannot allocate 2818048-byte block (534708224 in use)
throw: out of memory
私は、私が行方不明ですシンプルなものがある把握。私はGoがgreyLevels()に割り当てられたメモリの割り当てを解除すると思ったが、そうは思わないだろうか?
はフォローアップ:
greyLevelsのすべての呼び出し後runtime.GCを()を挿入した後、メモリ使用量をならし。昨夜、私は約800枚の画像に向かっていきました。今日私はそれを入力セット全体、約6800の画像上で実行させました。 1500枚の画像の後
は、トップは次のようになります。
top - 10:30:11 up 41 days, 11:47, 2 users, load average: 1.46, 1.25, 0.88
Tasks: 135 total, 2 running, 131 sleeping, 1 stopped, 1 zombie
Cpu(s): 49.8%us, 5.1%sy, 0.2%ni, 29.6%id, 15.0%wa, 0.0%hi, 0.3%si, 0.0%st
Mem: 3090304k total, 2921108k used, 169196k free, 2840k buffers
Swap: 3135484k total, 31500k used, 3103984k free, 640676k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28474 mtw 20 0 2311m 1.8g 412 R 99 60.5 16:48.52 8.out
、別の5000枚の画像を処理した後、堅調に推移しました。
Goバージョン、OSプラットフォーム、CPUアーキテクチャ情報を追加してください。また、問題を再現する完全なコードが役立ちます。 – zzzz
@jnml "out of memory ..."(534708224使用中)からCPUアーキテクチャを推論することができます。 –
@Atom:IntelまたはARM? ;-) – zzzz