4

私は非常に大きなプロジェクトでmt4jライブラリを使用しています。このプロジェクトでは、シーンが定期的にプッシュおよびポップされます。mt4jは、処理ライブラリを使用して画像を処理します。

このメソッドを使用してloadImage()画像をロードしますが、シーンがポップされたときにこれらの画像をメモリから削除する方法がわかりません。アプリケーションの実行中に使用されるメモリが増えるため、実際にはメモリの問題が発生します。

何か考えがありますか?

ありがとうジェレミー

編集 :

ImageManagerクラスを作成しました:

package managers;

import java.util.HashMap;
import java.util.Map;

import org.mt4j.MTApplication;

import processing.core.PImage;




public class ImageManager {

private static ImageManager mImageManager = null;

protected MTApplication mApp;
protected Map< String, PImage > mImages;

protected PImage mTempImg;

private ImageManager( MTApplication app ) {
    mApp = app;
    mImages = new HashMap< String, PImage >();
}

public static synchronized ImageManager getInstance( MTApplication app ) {
    if( mImageManager == null ) {
        mImageManager = new ImageManager( app );
    }

    return mImageManager;
}

/**
 * Load or retrieve img in memory
 * 
 * @param path Path to the image
 * @return <PImage> the image
 */
public PImage getImage( String path ) {
    // Search for image
    if( mImages.containsKey( path ) ) {
        System.out.println( "ImageManager::getImage : image found !" );
        mTempImg = mImages.get( path );
    } 
    else {
        System.out.println( "ImageManager::getImage : image not found, loading" );
        mTempImg = mApp.loadImage( path );
        mImages.put( path, mTempImg );
    }

    return mTempImg;
}
}

これが私の問題です。メモリの問題に役立つと思いましたが、画像をロードするたびにメモリが増加します。使用例:

ImageManager imgManager = ImageManager.getInstance( (MTApplication) app );
            PImage image = imgManager.getImage( getPathToIcons() + imagesNames[i] );
            //PImage image = app.loadImage(getPathToIcons() + imagesNames[i]);
            mSceneImages.add( image );

何か案が ?ありがとう

編集2:実際、この方法はうまく機能しています:)問題は解決しました!

4

5 に答える 5

2

それとも単にそれらを再利用しますか?最初に、image1 = loadImage(oneImage)、後でimage1 = loadImage(anotherImage)?

于 2012-10-10T17:01:38.790 に答える
2

Java でのメモリ リークについては、packratting を調べることができます。実行する以外に処理するための優れたソリューションが見つかりませんでした

トップ-s 5

(UNIX システムの場合) ハングするまでメモリ使用量を監視します。私は最近、ArrayList で潜在的に数千の blitt (私の場合は opengl で使用するテキストの画像) を作成していた datavis プロジェクトに取り組んでいました。もともと、データをロードするたびにこれらの配列をオンザフライで再作成していましたが、それが「メモリ リーク」の原因でした。

私の場合、オブジェクト参照を無効にして、具体的にガベージ コレクターを呼び出してみました。処理が void draw() メソッドを 1 秒間に 60 回以上呼び出す可能性があるという事実に関係している可能性があると思いますが、参照を手放すことはないようです。

問題を修正するために私がしたことは、setup method() で一度だけすべての画像をロードし、ブリットを作成し、新しいデータがあったときにのみ新しい項目を ArrayList に追加することでした。

これより前は、ArrayList 全体をオンザフライで再作成するだけでした。十分に高速に思えたからですが、長時間実行すると、この恐ろしいメモリ リークの問題が発生しました。

これで、毎回新しいオブジェクトと ArrayList を作成するのではなく、この参照にブリットが割り当てられました。それははるかに効率的で、同じメモリの問題に悩まされることはありませんでした.

たとえば、次のようなものです (ループで何千回も実行します)。

tempImage = imageArrayList.get(i); // just assigns a reference, does not create a new object

このようなものの代わりに:

tempImage = loadImage("image.jpg"); // this creates a new object every time it is called
于 2012-10-10T21:52:39.990 に答える
1

LoadImage は PImage オブジェクトを返します。これらの PImage 参照を破棄すると、ガベージ コレクターである System.gc() がそれらを削除する必要があります。あなたはそれを試しましたか?

于 2012-10-10T16:46:45.653 に答える
1

Processing 2.x を使用していますか? もしそうなら、処理フォーラムのこのスレッドが答えになるかもしれません。どうやら 2.x で画像を使用するとメモリ リークが発生するようです。また、彼らはあなたが試したいかもしれない回避策を指摘しています。ここでは、私が指摘したスレッドの PhiLho からのハックの例を示します。HTH。

void draw()
{
  PImage img = createImage(width, height, RGB);
  image(img, 0, 0);
  g.removeCache(img);// this is avoiding the leak
  println(frameCount + " " + g.getCache(img));
}
于 2012-11-29T20:14:00.927 に答える
0

編集:最後に一度に画像を削除しようとしましたが、メモリを消去しません...見つからない他の参照がまだいくつかあるようです...メモリの消去を確実にするためのアイデアはありますか?

問題に対する私の解決策: ImageManager クラス

package managers;

import java.util.HashMap;
import java.util.Map;

import org.mt4j.MTApplication;

import processing.core.PImage;




public class ImageManager {

private static ImageManager mImageManager = null;

protected MTApplication mApp;
protected Map< String, PImage > mImages;

protected PImage mTempImg;

private ImageManager( MTApplication app ) {
    mApp = app;
    mImages = new HashMap< String, PImage >();
}

public static synchronized ImageManager getInstance( MTApplication app ) {
    if( mImageManager == null ) {
        mImageManager = new ImageManager( app );
    }

    return mImageManager;
}

/**
 * Load or retrieve img in memory
 * 
 * @param path Path to the image
 * @return <PImage> the image
 */
public PImage getImage( String path ) {
    // Search for image
    if( mImages.containsKey( path ) ) {
        System.out.println( "ImageManager::getImage : image found !" );
        mTempImg = mImages.get( path );
    } 
    else {
        System.out.println( "ImageManager::getImage : image not found, loading" );
        mTempImg = mApp.loadImage( path );
        mImages.put( path, mTempImg );
    }

    return mTempImg;
}
}
于 2012-10-11T10:23:46.640 に答える