3

私は、JavaFXを活用して、20〜30秒ごとに大量の画像コンテンツを画面の内外にスクロールするアプリケーションを作成しています。これは、数時間実行して、完全に新しいコンテンツを取り込み、数分ごとに古いコンテンツを破棄できるようにすることを目的としています。システムに512Mbのグラフィックメモリがあり、数分後、そのメモリはすべてJavaFXによって消費され、JavaFXシーンで何をしても、どのメモリも解放されません。ノードがシーンから外れたときにノードを破棄するように細心の注意を払っています。一度にメモリに保存できる画像ノードは多くても50〜60個です。これらの画像をバックアップしていたグラフィックメモリのハードリリースを実行できる必要がありますが、JavaFXの画像インターフェイスは非常に高レベルであるため、その方法を理解できていません。

java.awt.image.Imageでflush()メソッドのようなものを探しています:http: //docs.oracle.com/javase/7/docs/api/java/awt/Image.html#flush()

Linuxでjava7u13を実行しています。

編集:

潜在的な回避策を見つけることができましたが(以下を参照)、JavaFX JIRAチケットを入力して、上記の機能をリクエストしました。

RT-28661ノードのネイティブリソースクリーンアップ機能への明示的なアクセスを追加します。

4

2 に答える 2

1

おそらく、次の問題の根本原因に関連する動作が発生しています。

RT-16011PGノードがシーングラフの一部でなくなったことを知るためのメカニズムが必要

問題の説明から:

一部のPGノードには、GPUテクスチャなどの非ヒープリソースへのハンドルが含まれています。これらのハンドルは、ノードがシーングラフの一部でなくなったときに積極的に再利用する必要があります。残念ながら、リソースを解放できるようにこの状態の変化を報告するメカニズムはありません。そのため、リソースを再利用するには、GC、Refキュー、場合によってはファイナライズの組み合わせに依存する必要があります。これらのリソースの一部を遅延再生すると、ガベージコレクションが遅れ、これらの限られたリソースが不足した場合に例外が発生する可能性があります。

リンクした問題ページを見ると、他にも多くの関連する問題があります(問題を表示するにはサインアップが必要ですが、誰でもサインアップできます)。

関連する問題の例は次のとおりです。

シーンから削除されたキャッシュノードに関連付けられたRT-15516画像データは積極的にリリースされません

ユーザーがコメントしたもの:

私のアプリの回避策は、頻繁に使用するすべてのノードに対して、現金の使用をfalseに設定するだけであることがわかりました。クラッシュすることなく2日間作業。

したがって、ノードでsetCache(false)を呼び出してみてください。

また、これらの問題のいくつかが修正されたJava 8プレビューリリースを使用してみて、アプリケーションの安定性が向上するかどうかを確認してください。現在、Java 8ブランチでも、次のような未解決の問題があります。

RT-25323Prism用の統合されたTextureリソース管理システムが必要

現在、テクスチャリソースは、その使用方法に応じて、少なくとも2か所で個別に管理されています。1つは画像のテクスチャキャッシュで、もう1つはRTTのImagePoolです。このアプローチには設計上の欠陥があります。つまり、2つのキャッシュは互いに認識せず、システムに無制限のネイティブリソースがあることを前提としています。

より多くのメモリを搭載したビデオカードを 使用すると、問題が軽減または解消される場合があります。

また、問題を示す最小限の実行可能例をまとめ、JavaFXランタイムプロジェクトに対してバグリクエストを発生させて、JavaFX開発者がシナリオを調査し、それが既知の問題の新規または重複であるかどうかを確認することもできます。

于 2013-02-21T18:22:57.570 に答える
1

私が思いついた最善の回避策は、JVMの最大ヒープをグラフィックカードの使用可能な制限の半分に設定することでした。(私は512mbのグラフィックメモリを持っているので、これを-Xmx256mに設定します)これにより、GCは破棄されたjavafx.image.Imageオブジェクトをより積極的にクリーンアップし、JavaFX側でグラフィックメモリのクリーンアップをトリガーするように見えます。 。

以前、ヒープスペースは512mbに設定されていました(システムメモリは4GBなので、これは非常に管理しやすい制限です)。これに伴う問題は、JVMがこの512 MBの制限に近づき始めるまで、イメージのクリーンアップについて非常に怠惰であったことのようです。すべての画像データがグラフィックメモリにコピーされたため、JVMが実際にクリーンアップを気にし始める前に、グラフィックメモリを使い果たした可能性が高いことを意味します。

私はjewelseaによる提案のいくつかを試しました:

setCache(false)を呼び出しているので、これはプラスの影響を与える可能性がありますが、最大ヒープサイズを下げるまで改善に気づきませんでした。

Java8で実行してみたところ、いくつかの良い結果が得られました。グラフィックメモリ管理ではより適切に動作するように見えましたが、それでもすべてのメモリを使い果たし、ほとんどなくなるまでグラフィックメモリを気にし始めなかったようです。アプリケーションのヒープ制限を減らすことが不可能な場合は、Java8プレリリースを評価する価値があるかもしれません。

JavaFXプロジェクトにいくつかの機能リクエストを投稿し、JIRAチケットへのリンクを提供します。

于 2013-02-22T16:14:53.683 に答える