問題タブ [memory-layout]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C のスタック フレームについて
C でスタック フレームを理解しようとしているので、スタック フレームを分析する簡単な C コードを書きました。
まず最初に、fun1() は 10 に初期化されたローカル変数のアドレスを ptr に返しますが、これは警告につながりますが、それは問題ありません... *ptr の値を出力すると、10 が出力されますが、それでも問題ありません.. .
次の fun2() は、初期化さえされていないローカル変数のアドレスを返します。 *ptr の値を出力しようとすると、a または b のアドレスを返すかどうかに関係なく、10 が出力されます...
ここで実際に何が起こっているのかを理解するために、gdb を利用しました。gdb を使用して、段階的なデバッグを開始し、fun2()の「 return &a 」の行に到達したとき、b のアドレスを出力しようとしましたが 、 &bを出力しようとしましたが、 Can't take address of "b" which is not を出力しました左辺値。
a のアドレスを出力しようとすると、 &aを出力するとまったく問題なく出力されるのに、なぜ b のアドレスが出力されないのかわかりません。* a が左辺値であるのに b が左辺値でないのはなぜですか?
c++ - POD 構造体を派生型にキャストする
従来のプロジェクターで作業しているときに、ネットワーク経由でデータを転送するために POD 構造体が使用されているというパターンに出会いました。
受信側では、データは POD タイプのオブジェクトに受信されます。その後、PODType からクラスが派生し、受信したオブジェクトが C スタイルのキャストで派生クラスにキャストされ、データにアクセスするいくつかのメソッドが使用されます。
派生クラスにはパブリック メソッドとプロテクト メソッドがあるため、もはや POD ではありません。これが継承の悪用であることはわかっていますが、長い間コード ベースにありました。
それが標準的な観点から動作することが保証されているかどうか疑問に思っています (C++03 または C++98)。派生クラスには独自のデータ メンバーや仮想関数はありませんが、一方が POD で他方がそうでない場合、メモリ レイアウトが同一であることが保証されているかどうかはわかりません。d.data
コンパイラは、POD 基本クラスの場合と同様に、DerivedFromPOD 型のオブジェクト d のアドレスと のアドレスが同じになるように DerivedFromPOD を配置する必要がありますか?
javascript - Javascript のメモリ レイアウト - データ指向設計とオブジェクト指向設計の比較
C/C++ のバックグラウンドから来て、キャッシュ ミスの削減に関するオブジェクトのメモリ レイアウトは、特にコンソールで作業する場合に重要です。データ指向の設計は、オブジェクト指向の設計よりも好まれることがよくあります。これは、関連するオブジェクトをメモリ内で (特にパフォーマンスが重要な領域で) 互いに近くに保つのに役立つためです。
最近、私はいくつかの Javascript 開発を行っていますが、Javascript コミュニティー内で一般的なコンセンサスがどのようなものか疑問に思っています。
Javascript の経験が限られているため、プロファイリング時にまったく予想外の結果が得られて驚くことがよくあります。Javascript オブジェクト/構造の内部メモリ レイアウトと実装は、ブラウザーによって大きく異なるため、最適化を試みる価値があるかどうか疑問に思います。
2 つのメソッドのパフォーマンスを比較するために jsPerfで簡単なテスト ケース ( http://jsperf.com/object-vs-data ) を作成しました。Chrome ではパフォーマンスの向上が示されていますが、Safari では顕著なスピードアップは見られませんでした。
Javascript では、オブジェクトのメモリ レイアウトにさえ気を配る必要がありますか? それとも、「ある方法で実装し、必要に応じて最適化する」タイプのものですか?
この 2 番目のオプションは、特に従うべき適切なガイドラインがある場合は、(開発時間の点で) 無駄に思えます。
ありがとう〜
補足情報: これは基本的に、Javascript で 2 つのアプローチを実装する方法です。上記の jsPerf テスト ケースは次のように実装されます。
c++ - C++: 継承を使用したクラスのメモリ レイアウト
データのパック方法が標準で指定されていないことは知っています。私はクラスのメモリレイアウトについてのアイデアを得ようとしていました(特にdynamic_cast<void*>
、最も派生したクラスの先頭へのポインターを返すことを保証する方法)。次のコードの出力についての説明は思いつきませんでした:
ポインターの値を出力すると、a
、c
、d
が常に同じ値を持ち、b
オフセットとして 4 バイトが追加されるだけであることがわかります。偶然ですか?それともその背後にロジックがありますか?
編集:
概念的にはレイアウトは画像のようにする必要がありますが、どういうわけかポイントA、C、Dが1つにマージされます。
java - 圧縮された Oops がオブジェクト ヘッダーに 12 バイトを与える理由
これは Java 6 メモリ モデルの後です。32 ビット JVM では、オブジェクトの浅いサイズは
最初の 2 つの項の合計が 8 の倍数にならない場合は、パディングが行われます。
64 ビット JVM では、浅いサイズは
私の理解では、この Object ヘッダーは 2 つの単語 (oracle hotspot VM) で構成されています。
- クラスワード
- マークワード
32 ビット JVM では、オブジェクト ヘッダー = 2 * 32 ビット = 64 ビット = 8 バイト
64 ビット JVM では、オブジェクト ヘッダー = 2 * 64 ビット = 128 ビット = 16 バイト
ただし、CompressedOops を使用すると、下位 3 ビットが切り捨てられるため、32 ギガ未満のヒープの場合、64 ビット JVM では 8 バイトに戻るはずです。
しかし、JOL (Java Object Layout) を使用してオブジェクト レイアウトをテストしたところ、オブジェクト ヘッダーに 12 バイトが表示されました。
テストコード
出力
これらの追加の 4 バイトを追加するために、ここで欠けているのは何ですか?
rust - 構造体、タプル、タプル構造体のメモリ レイアウトは何ですか?
リファレンス マニュアルから明らかなように、s のメモリ レイアウトstruct
は指定されていません(repr
属性が使用されていない場合)。この規則により、コンパイラは、フィールドを並べ替えて構造をより密にパックすることができます。
タプルとタプル構造体のメモリ レイアウトはどうですか? それはどのように(未)指定されており、その理由は何ですか?
c - const 文字列はどこに格納されますか? スタックまたは.data?
以下に示す簡単なc
コードを作成しました。このコード スニペットでは、const 文字列abcd
が格納されている場所を確認します。.data
最初に、読み取り専用のセクションに保存する必要があると思います。しかし、Debian でのテストの後、状況は私が最初に推測したものとは異なります。gcc で生成されたアセンブリ コードを確認すると、 function のスタック フレームに配置されていることがわかりましたp
。しかし、後でOSXで試してみると、文字列が.data
再びセクションに保存されます。今、私はこれに混乱しています。const 文字列を格納するための標準はありますか?
更新: rici の答えは私を目覚めさせます。OSX では、最初のリテラルが格納され.data
、後で関数のスタック フレームに移動されます。したがって、この関数のローカル変数になります。ただし、Debian の gcc は、この状況を処理するため、OSX とは異なります。Debian では、gcc はリテラルを から移動するのではなく、直接スタックに格納しました.data
。不注意で申し訳ありません。
rust - Rustでの正確なメモリレイアウト制御?
私の知る限り、Rust コンパイラは、構造体の各フィールドにパック、並べ替え、およびパディングを追加できます。必要な場合、正確なメモリ レイアウトを指定するにはどうすればよいですか?
C# ではStructLayout
属性があり、C/C++ ではさまざまなコンパイラ拡張機能を使用できました。期待される値の位置のバイト オフセットを確認することで、メモリ レイアウトを確認できました。
正確なメモリ レイアウトを必要とするカスタム シェーダーを使用する OpenGL コードを記述したいと考えています。パフォーマンスを犠牲にせずにこれを行う方法はありますか?