Come gestire una variabile membro che consuma memoria

5

Supponiamo che più oggetti della stessa classe debbano fare qualcosa che richiede una risorsa che consuma memoria. Quale dei seguenti approcci è raccomandato per definire e utilizzare la risorsa in base agli oggetti?

  • Ogni oggetto crea la risorsa nel proprio
  • Dichiara un'istanza di risorsa e passa a ciascun oggetto
  • Utilizzo di un oggetto statico per la risorsa

Fammi dare un esempio

class Section 
{
     public Bitmap Page {/* set and get the page...*/}
     Bitmap page = new Bitmap(600,800);
     Draw(SomeThing s) 
     {
        // Draw something on the page
     }
}

// in somewhere else
foreach (Section sect in Sections)
{
     sect.Draw(something);
     Video.AddFrame(sect.Page);
}

Versus.

class Section 
{
     public Bitmap Page {/* set and get the page ...*/}
     Bitmap page; // it isn't instantiated in the class
     Draw(SomeThing s) 
     {
        // Clear the page
        // Draw something on it
     }
}

// in somewhere else
Bitmap screen = new Bitmap(600,800); // the common resource
foreach (Section sect in Sections)
{
     sect.Page = screen;
     sect.Draw(something); // it clears it before drawing something on it
     Video.AddFrame(screen);
}

Versus.

class Section 
{
     public Bitmap Page {/* set and get the page ...*/}
     static Bitmap page = new Bitmap(600,800);
     Draw(SomeThing s) 
     {
        // First Clear the page
        // Draw something on the page
     }
}

// and in somewhere else
foreach (Section sect in Sections)
{
     sect.Draw(something);
     Video.AddFrame(sect.Page);
}

Per prima cosa ho usato il primo approccio ma ho consumato molta memoria dato che ogni oggetto nel mio array Sections aveva una bitmap. Poi sono stato costretto a provare il secondo approccio. Questo nuovo approccio è migliore del primo su tutti gli aspetti? Qual è la linea guida per tali situazioni?

    
posta Ahmad 04.12.2014 - 11:57
fonte

3 risposte

1

Questo dipende molto dal threading del modello utilizzato dall'applicazione.

  • In uno scenario sequenziale a thread singolo passerei o bitmap in giro (se la costruzione è un'operazione costosa) o l'ho creato / distrutto ogni volta. Ma devi creare oggetti di tale memoria intensiva immediatamente prima di essere utilizzati e distruggerli non appena non ne hai più bisogno, se possibile. Non crearli nel costruttore e lasciarli in giro.
  • Se stiamo per inserire il multithreading puoi creare un pool sicuro di thread (se la costruzione di una bitmap è costosa nello scenario) o semplicemente creare / distruggere ogni volta che ne hai bisogno. Ma ancora una volta, non creare oggetti solo per divertimento. Creale quando ne hai bisogno.
risposta data 31.01.2015 - 21:29
fonte
2

Se non esiste una singola bitmap per ogni sezione, probabilmente non vale la pena nemmeno di avere un membro nella sezione che punta alla bitmap. Potresti invece passare la bitmap come parametro al metodo Draw:

class Section 
{
     Draw(Bitmap page, SomeThing s) 
     {
        // Draw something on the page
     }
}


// somewhere else

Bitmap screen = new Bitmap(600,800); // the common resource

foreach (Section sect in Sections)
{
     sect.Draw(screen, something);
     Video.AddFrame(screen);
}

In questo modo è più flessibile e potresti decidere di creare una nuova risorsa ovunque usi i metodi della sezione.

    
risposta data 07.01.2015 - 22:02
fonte
0

Potresti voler usare un BitmapLoader che carica pigramente le Bitmap come e quando richiesto. In questo modo non devi mantenere alcun membro interno. Se necessario, puoi implementare una sorta di caching LRU in BitmapLoader per ottimizzare il caricamento dei bitmap con accesso più frequente.

    
risposta data 04.03.2015 - 14:34
fonte

Leggi altre domande sui tag