0

c の LinkedList の例を考えてみましょう。ここでは、低速の malloc と free を使用する代わりに、プールまたはノードのスタックとして使用するために、スタック上に N 個のノード構造体を明示的に事前に割り当てています (実行中にノードを解放する機能は必要ないので、スタックで十分です):

#define N 40000

typedef struct node_t {
    void * ele;
    struct node_t * next;
}node,*Pnode;

node Stack[N];//memory allocation for the linkedlist nodes
int sp=0;

Pnode createNode(void * x) {
    Pnode temp=&Stack[sp++];
    temp->ele=x;
    temp->next=NULL;
    return temp;
}

上記のアイデアを Java で模倣しようとしたとき、それが思いつきました... Node[] スタックを、メモリが STACK で事前に割り当てられたノード オブジェクトの配列にするクラスを完成できますか?

public class Node<E>  {

    private final static int n = 40000;
    private static Node[] stack = ?
    private static int sp = 0;

    private E ele;
    private Node next;

    private Node () {}
    public Node createNode(E e) {
        stack[sp].ele=e;
        stack[sp].next=null;
        return stack[sp++];
    }
}

基本的に、これを知りたいのは、自分のプログラムで何ができるようにしたいのかを知っているからです。また、メモリ ブロックを解放して再利用する機能は必要ないこともわかっています。Node オブジェクトをすばやく割り当てることができるようにしたいのです。私のプログラムがほとんどHEAP OVERFLOWを持っているときでさえ、稲妻として。最大容量 N のノードのスタックと、私が行ったような実行中のインデックスは、私にとって完璧です...

4

3 に答える 3

6

いいえ。Java には、スタックにメモリを割り当てるための明示的なメカニズムがありません。

を使用するnewことが、メモリを割り当てる唯一の方法です。そのメモリがどこから来るかを決定し、その時点からそれを管理するのは JVM 次第です。

編集:コードを詳しく調べました。スタックにメモリを割り当てていません。あなたがしているように見えるのは、データセグメントに存在するスタックデータ構造を持ち、自分で管理することです。

Java では、次のものに直接相当するものはありません。

node Stack[N];

Nつまり、連続したメモリ ブロック内にオブジェクトを構築する方法はありません。参照の配列を割り当ててから、オブジェクトNを作成する必要がありNます。

とはいえ、最新の JVM では、 はnew基本的にポインター バンプに相当することに注意してください。これは: (a) 安い。(b) で行っていることに似ていますsp

于 2012-04-24T14:28:47.257 に答える
1

Node[] を STACK 内のノード オブジェクトの配列にするクラスを完成できますか?

いいえ。Java は独自のヒューリスティックに基づいてメモリの割り当てを管理します。私の知る限り、JLS には、特定のオブジェクトがどこに割り当てられるかを保証するものは何もありません。

あなたへの私の質問は、なぜこれをスタックに割り当てたいのですか? ガベージ コレクターの内部状態に基づいて、このデータの最もパフォーマンスの高い場所がホットスポットよりもよくわかっていると思いますか? (明らかに専門家ではない私の知識に基づくと、これらのオブジェクトはヒープ上の Eden プールに配置するのが最適です。)

Java について学ぶ必要があることの 1 つは、単に手放し、メモリを割り当てる場所に関する VM の決定を信頼することです。複雑なアルゴリズムを記述しない限り、一般的にこれらの決定は非常にうまく機能します (通常、コードを記述するときに静的な二分法を強制されるのではなく、実行時に利用可能な情報を考慮するため、開発者よりも優れています)。

于 2012-04-24T14:30:07.420 に答える
1

あなたが望んでいるように見えるのは、オブジェクトプールです。

単純なプールは ArrayList を使用することです

public class Node<E>  {

    private final static int MAX_SIZE = 40000;
    private final static List<Node> freeNodes = new ArrayList<>();

    private E ele;
    private Node next;

    private Node () {}

    public static Node<E> acquireNode(E e) {
        Node node = freeNodes.size() > 0 
                    ? freeNodes.remove(freeNodes.size()-1) 
                    : new Node();
        node.ele = e;
        return node;
    }

    public static void freeNode(Node<E> node) {
        if(freeNodes.size() < MAX_SIZE) {
            node.next = null;
            freeNodes.add(node);
        }
    }
}

多くのオブジェクトを作成するためにバインドされた LinkedList を使用する代わりに、そもそもこれらのノードを必要としない ArrayList や RingBuffer などの別の構造を使用することをお勧めします。(何かをする最も速い方法は、何もしないことです;)

于 2012-04-24T14:40:44.473 に答える