0

学校の課題のために、メモリ アクセス用のシミュレーションを作成する必要があります。まず、1 つ以上のトレース ファイルを読み取る必要があります。それぞれに、各アクセスのメモリ アドレスが含まれます。例:

0 F001CBAD
2 EEECA89F
0 EBC17910
...

最初の整数が読み取り/書き込みなどを示す場合、16 進メモリ アドレスが続きます。このデータを使用して、シミュレーションを実行することになっています。したがって、私が持っていたアイデアは、これらのデータをArrayList<Trace>メモリアドレスとアクセスタイプ(文字列と整数のみ)を含む単純なクラスであるトレース(今のところJavaを使用しています)に解析することでした。その後、これらの配列リストをループして処理する予定です。

問題は解析時でもあり、ヒープスペースが不足しています。各トレース ファイルは最大 200 MB です。私は最大8つ持っています。つまり、「キャッシュ」しようとしているデータの最小〜1.6 GBを意味しますか? 私を困惑させているのは、タスクマネージャーによると、1つのファイルのみを解析していて、Javaが2GBを使用していることです...

これを行うより良い方法は何ですか?

コード スニペットはCode Reviewにあります。

4

3 に答える 3

1

rolfl のように、コード レビューであなたの質問に答えました。私にとって最大の問題は、最初にすべてをメモリに読み込んでから処理することです。一定量を読み取り、それを処理し、完了するまで繰り返す必要があります。

于 2013-11-07T13:07:48.800 に答える
1

私が codereview で与えた答えは、ここで使用する必要があるものと同じです.....

ただし、複製は問題ないように見えるため、ここで回答を複製します。


問題はほぼ確実にTraceクラスの構造にあり、それはメモリ効率です。instrTypehexAddressがメモリ効率の良い構造として格納されていることを確認する必要があります。instrType は のように見えますが、これは良いことですが、Trace クラスでintとして宣言されていることを確認してください。int

可能性が高い問題は、hexAddress 文字列のサイズです。気付いていないかもしれませんが、文字列はメモリを「リーク」することで有名です。この場合、 がありline、そこから hexString を取得しているだけだと思います... しかし実際には、hexString には行全体が含まれています.... ええ、本当に。たとえば、次のコードを見てください。

public class SToken {

    public static void main(String[] args) {
        StringTokenizer tokenizer = new StringTokenizer("99 bottles of beer");
        int instrType = Integer.parseInt(tokenizer.nextToken());
        String hexAddr = tokenizer.nextToken();
        System.out.println(instrType + hexAddr);
    }
}

ここで、IDE (私は eclipse を使用) にブレークポイントを設定して実行すると、hexAddr に行全体の char[] 配列が含まれ、オフセットが 3 でカウントが 7 であることがわかります。 .

String 部分文字列やその他の構成要素が機能する方法により、短い文字列のために大量のメモリを消費する可能性があります... (ただし、メモリは他の文字列と共有されます)。結果として、基本的にファイル全体をメモリに保存しています!!!!

少なくとも、コードを次のように変更する必要があります。

hexAddr = new String(tokenizer.nextToken().toCharArray());

しかし、さらに良いのは次のとおりです。

long hexAddr = parseHexAddress(tokenizer.nextToken());
于 2013-11-07T12:44:03.090 に答える
0

java.nio.ByteBufferの代わりにクラスを使用してみてくださいjava.util.ArrayList<Trace>。また、メモリ使用量も削減する必要があります。

class TraceList {

    private ByteBuffer buffer;

    public TraceList(){
        //allocate byte buffer
    }

    public void put(byte operationType, int addres) {
        //put data to byte buffer
    }

    public Trace get(int index) {
        //get data from byte buffer by index
        byte type = ...//read type
        int addres = ...//read addres
        return new Trace(type, addres)
    }

}
于 2013-11-07T13:00:03.867 に答える