1

内部にシリアル化された HashMap を含む 1.5 GB のファイルがあります。

これを HashMap 変数に読み込む Mapper クラスに setup() メソッドがあります。

読み取りメソッドに移動できるように見えますが、すぐにタスクの Java ヒープ スペース エラーがスローされます。

mapred.child.opts パラメーターを設定する必要があるかもしれないという多くの議論を読んで、メイン プログラム コード内でそれを実行しています。

私は使用しています: conf.set("mapred.child.java.opts.", "-Xmx1024M");

さらに数を増やしてみました。シリアル化されたファイルを HashMap 変数に読み込もうとしているときに、同じエラーがスローされ続けるのはなぜですか?

私の setup() メソッドのコードは次のとおりです。

try {
        test="hello";
        Path pt=new Path("hdfs://localhost:9000/user/watsonuser/topic_dump.tsv");
        FileSystem fs = FileSystem.get(new Configuration());
   }catch(Exception e) {System.out.println("Exception while reading the nameMap 
                          file."); e.printStackTrace();}          
        InputStream is = fs.open(pt);
        ObjectInputStream s = new ObjectInputStream(is);  
        nameMap = (HashMap<String, String>) s.readObject(); 
        s.close();
    }catch(Exception e) {
        System.out.println("Exception while reading the nameMap file."); 
        e.printStackTrace();
    }
4

1 に答える 1

1

シリアライズされたバージョンのハッシュ マップを使用していて、ファイルの最終的な出力サイズが 1.5 GB であるため、JVM が必要とするメモリの量は少なくとも 1.5​​ GB であると推測しています。

ファイルにロードする小さなプログラムでこれをテストできるはずですが (既に持っているように)、メモリ エラーが表示されなくなるまで -Xmx 値を増やし続けます。これがベースラインになります (おそらくまだスピルのソートなどのためのバッファサイズ要件があるため、hadoop マッパー内で実行する場合はさらに追加する必要があります。

また、このハッシュ マップで表されているビンとアイテムの数も知っていますか? HashMap の実装は、そのビン番号にハッシュされるエントリ項目がリンクされた単なるビンの配列です。ビンの数も 2 の累乗である必要があるため、マップにアイテムを追加すると、マップがしきい値 / 負荷係数 (0.75) に達すると、実際のバッキング アレイのメモリ要件が 2 倍になります。これを念頭に置いて、あなたが見ている問題は、メモリに逆シリアル化されたときに、このような大きなハッシュ マップ (シリアル化された 1.5GB) が、より大きなメモリ フットプリントではないにしても、同じくらい大きなメモリ フットプリントを必要とすることであると想像します。

于 2013-03-20T10:41:08.610 に答える