問題タブ [large-object-heap]

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.

0 投票する
7 に答える
19466 参照

c# - 32 ビット .NET プロセスで 1,000 MB を超えるメモリを割り当てる

32 ビットの .NET プロセスで 1,000 MB を超えるメモリを割り当てられないのはなぜでしょうか。次のミニ アプリケーションは、1,000 MB を割り当てた後に OutOfMemoryException をスローします。なぜ 1.8 GB ではなく 1,000 MB なのですか? 変更できるプロセス全体の設定はありますか?

PS: ガベージ コレクションは役に立ちません。

編集して、私が望むものを明確にします。データベース/ディスクに書き込む前に非常に大量のデータを処理するサーバーアプリケーションを作成しました。すべての一時ファイルを作成する代わりに、メモリ内キャッシュを作成しました。これにより、全体が超高速になります。しかし、メモリには限りがあるので、その限界を調べてみました。そして、なぜ私の小さなテスト プログラムが正確に 1,000 MB の後に OutOfMemoryException をスローしたのか疑問に思いました。

0 投票する
4 に答える
8718 参照

.net - ジェネレーション 2 とラージ オブジェクト ヒープのみで GC.Collect

私のアプリケーションでは、多数の大きなオブジェクトがすべて一度に解放される特定の時間があります。その際、特にラージ オブジェクト ヒープ (LOH) でガベージ コレクションを実行したいと考えています。

GC.Collect(2)ジェネレーション 2 コレクションを実行しているときに GC が LOH でのみ呼び出されるため、呼び出す必要があります。GC.Collect(2)ただし、ジェネレーション 1 と 0で呼び出すと GC が引き続き実行されるというドキュメントを読みました。

GC にgen 2のみを収集させ、gen 1 または gen 0 を含めないようにすることは可能ですか?

それが不可能な場合、GC をそのように設計する理由はありますか?

0 投票する
5 に答える
493 参照

.net - 特定のタイプの .net 配列に割り当てることができる要素の実際の最大数を知るにはどうすればよいですか?

私は、.net のすべての配列が 2 GB に制限されていることを知っています。この前提の下では、配列に n = ((2^31) - 1) / 8 double を割り当てないようにしています。それにもかかわらず、その要素数はまだ有効ではないようです。sizeof(T) を指定して、実行時に要素の最大数を決定する方法を知っている人はいますか?

その数に近づく量が何であれ、要素がたくさんあることは知っていますが、すべての意図と目的のために、それが必要だとしましょう.

注: 私は 64 ビット環境にいて、AnyCPU のアプリケーション用のターゲット プラットフォームと、RAM に少なくとも 3100 MB の空き容量があります。

更新: 皆様の貢献に感謝し、私がとても静かで申し訳ありませんでした. ご不便をおかけして申し訳ございません。私は自分の質問を言い換えることができませんでしたが、それを追加することができます.私が探しているのは、次のようなものを解決することです:

私自身の回答の結果は、満足のいくものですが、十分ではありません。さらに、別のマシンでテストしていません (4 GB を超える別のマシンを見つけるのは難しいです)。その上、私は自分でいくつかの調査を行ってきましたが、実行時にこれを計算する安価な方法はないようです. とにかく、それは単なるプラスでした.私が達成しようとしているもののユーザーは、容量がなければ実装しようとしている機能を使用することを期待できません.

言い換えれば、配列の要素の最大数が 2GB ceteris paribusにならない理由を理解したいだけです。今のところ必要なのは最大値だけです。

0 投票する
6 に答える
3715 参照

c# - 断片化を防ぐために大きなオブジェクト ヒープを使用した直後に GC.Collect を呼び出す必要があります

私のアプリケーションは、大量のバイナリ シリアライゼーションと大きなオブジェクトの圧縮を行います。非圧縮のシリアル化されたデータセットは約 14 MB です。圧縮すると約 1.5 MB になります。データセットで serialize メソッドを呼び出すたびに、大きなオブジェクト ヒープのパフォーマンス カウンターが 1 MB 未満から約 90 MB に跳ね上がることがわかりました。また、比較的負荷の高いシステムでは、通常、このシリアライゼーション プロセスが数回発生するしばらく (数日) 実行した後、このシリアライゼーション メソッドが呼び出されると、アプリケーションがメモリ不足の例外をスローすることが知られています。メモリは十分にあるようです。断片化が問題であると推測しています (100% 確信しているとは言えませんが、ほぼ確実です)。

私が考えることができる最も簡単な短期的な修正(短期と長期の両方の答えを探していると思います)は、シリアル化プロセスが完了した直後に GC.Collect を呼び出すことです。私の意見では、これはLOHからオブジェクトをガベージコレクションし、他のオブジェクトを追加する前に行う可能性があります。これにより、断片化をあまり引き起こすことなく、他のオブジェクトがヒープ内の残りのオブジェクトにぴったりと収まるようになります。

このばかげた 90MB の割り当て以外に、失われた LOH を使用するものは他にないと思います。この 90 MB の割り当ても比較的まれです (約 4 時間ごと)。もちろん、そこにはまだ 1.5 MB の配列があり、おそらく他のいくつかの小さなシリアル化されたオブジェクトがあります。

何か案は?

良い反応の結果として更新

これが仕事をする私のコードです。私は実際にこれを変更して、シリアル化中に圧縮して、シリアル化が同時にストリームにシリアル化されるようにしましたが、あまり良い結果は得られませんでした。また、メモリ ストリームを 100 MB に事前割り当てし、同じストリームを 2 回続けて使用しようとしましたが、とにかく LOH は最大 180 MB になりました。Process Explorer を使用して監視しています。それは非常識です。次に UnmanagedMemoryStream のアイデアを試してみようと思います。

そうでない場合は、試してみることをお勧めします。この正確なコードである必要はありません。大規模なデータセットをシリアル化するだけで、驚くべき結果が得られます (私のものには、約 15 のテーブルがあり、文字列と列がたくさんあります)。

UnmanagedMemoryStream でバイナリ シリアル化を試行した後に更新する

UnmanagedMemoryStream にシリアル化しても、LOH は同じサイズにジャンプします。私が何をしても、BinaryFormatter を呼び出してこの大きなオブジェクトをシリアル化すると、LOH が使用されるようです。事前割り当てに関しては、あまり役に立たないようです。100MBを事前に割り当ててからシリアライズすると、170MBが使用されます。これがそのコードです。上記のコードよりもさらに簡単

真ん中の GC.Collect() は、LOH パフォーマンス カウンターを更新するためだけのものです。正しい 100 MB が割り当てられることがわかります。しかし、シリアライズを呼び出すと、すでに割り当てられている 100 の上にそれが追加されているように見えることに気付くでしょう。

0 投票する
1 に答える
373 参照

.net - マシンにページング メモリがないのに、Process.PagedMemorySize64 > 0 になるのはなぜですか?

ページ ファイル サイズがゼロに設定されたマシンで .net コードを実行しています。私のアプリケーションは System.Diagnostics.Process.PagedMemorySize64 をログに記録し、値 > 0 を示しています。

どうすればいいの?

PagedMemorySize64 のドキュメントには次のように書かれています。

このプロパティによって返される値は、プロセスによって使用される仮想メモリ ページング ファイル内のメモリの現在のサイズを表します。

私は何が欠けていますか?

背景:
メモリ リークがあるかどうかを判断するためにこれを行っています。System.Diagnostics.Process からのメモリ値は増加し続けていますが、使用しているプロファイルは増加していません。

ラージ オブジェクト ヒープの断片化を扱っている可能性があると思います。私のプログラムは、大きな画像の WPF スライド ショーを表示し、画像間にフェード アニメーションを表示しています。

どんな説明でも大歓迎です。

ありがとう。

0 投票する
6 に答える
9100 参照

c# - ラージアレイ、およびLOHフラグメンテーション。受け入れられている規則は何ですか?

おそらく他の未知のものの中でLOHフラグメンテーションを含む可能性のあるいくつかの絶望的なメモリの問題に関して、ここに他の活発な質問があります。

今の私の質問は、物事を行うための受け入れられた方法は何ですか?私のアプリをVisualC#で実行する必要があり、int [4000000]に合わせて大きな配列を処理する必要がある場合、ガベージコレクターがLOHを処理することを拒否することで、どうして運命づけられないのでしょうか。

大きな配列をグローバルにすることを余儀なくされているように思われ、それらの周りに「新しい」という言葉を使用することは決してありません。そのため、関数によって渡される適切なサイズの配列ではなく、「maxindex」変数を使用した不適切なグローバル配列が残ります。

これは悪い習慣だといつも言われてきました。どのような選択肢がありますか?

曲に何らかの機能はありSystem.GC.CollectLOH("Seriously")ますか?ガベージコレクションをSystem.GC以外にアウトソーシングする方法はありますか?

とにかく、大きな(> 85Kb)変数を処理するために一般的に受け入れられているルールは何ですか?

0 投票する
3 に答える
285 参照

.net - 構造体の配列が .NET のラージ オブジェクト ヒープ (LOH) に割り当てられたことを確認するにはどうすればよいですか?

CLR Profiler を使用していくつかの実験を行った結果、次のことがわかりました。

実行時に、構造体の配列 (または任意の配列) がラージ オブジェクト ヒープ (LOH) に割り当てられたことを確認するにはどうすればよいですか?

0 投票する
4 に答える
11364 参照

c# - Memorystream とラージ オブジェクト ヒープ

WCF を使用して、信頼性の低い接続を介してコンピューター間で大きなファイルを転送する必要があります。

ファイルを再開できるようにしたいのですが、WCF によってファイルサイズが制限されたくないので、ファイルを 1 MB にチャンクしています。これらの「チャンク」はストリームとして転送されます。これまでのところ、これは非常にうまく機能します。

私の手順は次のとおりです。

  1. ファイルストリームを開く
  2. ファイルからバイト[]にチャンクを読み取り、メモリストリームを作成します
  3. 転送チャンク
  4. 2.に戻り、ファイル全体が送信されるまで

私の問題はステップ 2 にあります。バイト配列からメモリ ストリームを作成すると、最終的に LOH になり、メモリ不足の例外が発生すると思います。私は実際にこのエラーを作成できませんでした。私の仮定が間違っている可能性があります。

ここで、メッセージで byte[] を送信したくありません。WCF から配列のサイズが大きすぎることが通知されるからです。最大許容配列サイズおよび/またはチャンクのサイズを変更できますが、別の解決策があることを願っています。

私の実際の質問:

  • 私の現在のソリューションは LOH にオブジェクトを作成しますか?それによって問題が発生しますか?
  • これを解決するより良い方法はありますか?

ところで、受信側では、受信したストリームから小さなチャンクを単純に読み取り、ファイルに直接書き込むので、大きなバイト配列は必要ありません。

編集:

現在の解決策:

0 投票する
2 に答える
412 参照

c# - 例外をスローするのではなく、ラージ オブジェクト ヒープが大きくなるのはなぜですか?

以前の質問で、LOH で割り当て可能な最大ブロックを最大化するプログラム的な方法を尋ねました。まだ問題が発生していますが、LOH のサイズが大きくなったり小さくなったりする理由を理解しようとしていますが、LOH の断片化が原因であると他の人が報告したものと一致する OutOfMemoryExceptions がまだ見られます。 .

たとえば、StringBuilder.EnsureCapacity を呼び出すと OutOfMemoryException がスローされるのに、別の場所から別の呼び出しを行うと LOH のサイズが拡大するのはなぜですか (パフォーマンス カウンターによると、拡大と縮小が繰り返されます)。

0 投票する
2 に答える
2158 参照

.net - 大きなオブジェクト ヒープの制限をプログラムで決定する

大きなオブジェクトにはIDisposalパターンを使用することをお勧めしますが、オブジェクトが「大きい」と見なされる制限を決定する信頼できる方法がないように見えるのはなぜでしょうか?

内部的には、LOH で割り当てられるオブジェクトの下限というような区別が存在します。それが 85k として公に伝えられるときはいつでも、同時に 1 つはその数に依存することを妨げられます。

特に、多くの「より大きな」配列を処理するアプリケーションの場合、適切なメモリ管理を実装し、LOH の断片化を防ぐために、その制限が必然的に必要になります。一方、「より小さい」配列の場合、IDisposal はメモリ消費の観点からは意味がありません。ここでは、圧縮 GC の方がはるかに優れています。

なんでそんなことないの

またはさらに良い:

編集: IDisposable パターンは、特別なオブジェクト (「大きな」オブジェクトまたは管理されていないオブジェクト) を適切に処理するための推奨事項にすぎません。私の質問は、ランタイムによるこれらのオブジェクトの特別な処理があると仮定していません。むしろ、オブジェクトが特別なメモリ管理に従うべきかどうかを知るために、パターンの実装者 (他の人もそうかもしれません) にランタイム サポートを求めます。