View Full Version : [java]Ridurre consumo memoria
Devo stampare a schermo un timer, per forza di cose devo aggiornare una stringa molto spesso... solo che controllando con memory monitor vedo che mi crea tantissimi char e String.
C'è modo per cambiare una stringa senza sprecare altra memoria?
Quello che faccio ora è un banale String.valueOf(int);
Il problema non sussiste se chiamo spesso il Garbage solo che mi sembra sia un'operazione un pò dispendiosa.
wingman87
02-03-2009, 18:02
Usa StringBuilder invece di String: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html
Ciao, in effetti dovevo specificare, si tratta di Java ME, e StringBuilder non è presente, però è presente StringBuffer, dovrebbe essere simile giusto?
banryu79
02-03-2009, 18:09
Ciao, in effetti dovevo specificare, si tratta di Java ME, e StringBuilder non è presente, però è presente StringBuffer, dovrebbe essere simile giusto?
Sì, la differenza è che StringBuffer è anche sincronizzato (un po' come la differenza che passa tra ArrayList e Vector in JavaSE).
wingman87
02-03-2009, 18:12
Sì, anzi a quanto leggo nella documentazione StringBuffer è threadsafe mentre StringBuilder non lo è, non so se a te serve anche questa peculiarità... ma ce l'ha. Di contro StringBuilder dovrebbe essere molto più veloce, ma non credo che la velocità sia ciò che ti serve
ok, vi spiego la situazione(banale), ho il tempo in secondi, devo solamente stamparlo.
Usando StringBuffer dovrei prima cancellare il contenuto e poi fare un append(int) giusto?
Se è così allora il problema rimane perchè durante il delete vengono usati dei char, e quando faccio StringBuffer.toString() viene creata un nuovo oggetto String.
Solo che il "ciclo" viene eseguito ogni 10 millisecondi quindi la spazzattura abbonda :D
Già che ci sono, se creo una classe atratta con costanti statiche dichiarate con final(ad esempio immagini) quando le richiamo vengono create solo la prima volta vero?
banryu79
03-03-2009, 09:10
Già che ci sono, se creo una classe atratta con costanti statiche dichiarate con final(ad esempio immagini) quando le richiamo vengono create solo la prima volta vero?
Non occorre che la classe sia astratta; non occorre che siano anche final: basta che siano membri static (e quindi sono considerati non membri di istanza, ma di classe)
Ti ringrazio, comunque sul fatto che vengano creati al momento della prima chiamata c'ho preso?
banryu79
03-03-2009, 12:07
Mi pare che i class member vengano istanziati quando il ClassLoader carica la classe per la prima volta durante l'esecuzione.
^TiGeRShArK^
03-03-2009, 13:36
:mbe:
ma scusa..
se il tempo è in secondi perchè aggiorni ogni 10ms? :mbe:
Non potresti controllare se il valore precedente è uguale a quello attuale e aggiornare solo in quel caso?
Anche perchè potrebbe anche avere problemi di flickering un'aggiornamento ogni 10ms...
in questo momento avresti dopo 10 minuti 600 oggetti anzichè 60k...
perchè il tempo principale è in centesimi, ma quello lo faccio senza stringhe, usando un array di char.
Mi è venuta in mente un'altra domanda, di solito non ci faccio molto caso a scegliere se usare un int piuttosto che un short o char quando si tratta di interi, ma voi come vi comportate invece?
Ad esempio se sapete che un valore non supera una certa soglia usata un short piuttosto che un int?
Mi è venuto in mente perchè programmando per cellulari la memoria non è che abbonda anzi...
C'è anche diffeerenza di velocità di elaborazione tra trattare int oppure char/short?
blackskop
03-03-2009, 22:58
Ma tu non sei quello che ha fatto quel giochino tipo worms in java? E fai queste domande da niubbo?
Si sono curiosità più che altro, e poi non sono mica un programmatore :)
E comunque la domanda principale non era tanto banale visto che la soluzione senza spreco di memoria non esiste...
Le altre in effetti si, ma erano cose che più o meno sapevo o avevo letto solo che ormai mi son dimenticato, è da parecchio che non tocco java.
Per il fatto dei tipi di dato effettivamente è una cosa che avrei sempre voluto chiedere, perchè non mi sono davvero mai preoccupdato di scegliere tra int o short salvo rari casi(i char spesso li uso invece).
Comunque sia io sono parecchio "niubbo", l'importante è sapere di esserlo giusto?
wingman87
03-03-2009, 23:09
Qual è il giochino?
Sulla velocità di elaborazione credo dipenda dall'architettura del cellulare o da come è stata implementata la JVM. Comunque perché non usi un array di char anche per i secondi?
blackskop
03-03-2009, 23:10
Nulla di personale, mi sembra solo strano che uno che riesce a realizzare un gioco più o meno complesso faccia domade sui tipi o sull'allocazione statica di oggetti. Tutto qua, ma vedo che hai gia risposto.
Qual è il giochino?
Sulla velocità di elaborazione credo dipenda dall'architettura del cellulare o da come è stata implementata la JVM. Comunque perché non usi un array di char anche per i secondi?
Il giochino era questo qua http://www.hwupgrade.it/forum/showthread.php?t=1304155
Volevo sapere se c'erano altre soluzione, e poi era più una fissa perchè volevo rapresentare i secondi come contatore quindi come valore crescente e non compreso fra 0 e 59.
Nulla di personale, mi sembra solo strano che uno che riesce a realizzare un gioco più o meno complesso faccia domade sui tipi o sull'allocazione statica di oggetti. Tutto qua, ma vedo che hai gia risposto.
Diciamo che avevo il presentimento di come andassero le cose non ci sono poi andato molto lontano dai :mc:
wingman87
03-03-2009, 23:37
Il giochino era questo qua http://www.hwupgrade.it/forum/showthread.php?t=1304155
Volevo sapere se c'erano altre soluzione, e poi era più una fissa perchè volevo rapresentare i secondi come contatore quindi come valore crescente e non compreso fra 0 e 59.
Ah, me lo ricordo, se guardi ero il primo ad averti risposto. Ma ti eri davvero ispirato a soldat?
Potresti crearti una classe che gestisca un contatore come un array di char, un char per ogni cifra, forse non è il massimo ma purtroppo non mi viene in mente altro per il momento.
cdimauro
04-03-2009, 00:37
Mi è venuta in mente un'altra domanda, di solito non ci faccio molto caso a scegliere se usare un int piuttosto che un short o char quando si tratta di interi, ma voi come vi comportate invece?
Ad esempio se sapete che un valore non supera una certa soglia usata un short piuttosto che un int?
Mi è venuto in mente perchè programmando per cellulari la memoria non è che abbonda anzi...
C'è anche diffeerenza di velocità di elaborazione tra trattare int oppure char/short?
Certo che c'è, specialmente coi cellulari, che montano CPU abbastanza limitate.
In questi casi cerca di usare il più piccolo tipo che riesce a rappresentare le quantità che manipoli.
Ma non ti fidare delle cose che ti potrebbero sembrare ovvie. A volte non non lo sono proprio. Ad esempio su alcuni cellulari il tipo boolean occupa 32 bit, cioé 4 byte; molto meglio, in questo caso, farne a meno e utilizzare un byte.
Quindi scrivi un'applicazione di test che ti tiri fuori tutte le informazioni di basso livello che ti servono: dimensione dei tipi standard, delle strighe che manipoli e delle istanze delle classi.
A proposito di classi: già la sola loro definizione (quindi senza nemmeno un'istanza creata) occupa spazio (su alcuni cellurari addirittura 500 byte circa, se non ricordo male), per cui cerca di usare meno classi possibili.
Inoltre utilizza quanto più possibile variabili e metodi static / final.
Esistono altri trucchetti per accelerare l'esecuzione dei cicli, ma sono troppo sporchi, per cui preferisco evitare di parlarne.
^TiGeRShArK^
04-03-2009, 01:53
perchè il tempo principale è in centesimi, ma quello lo faccio senza stringhe, usando un array di char.
mmm..
questo mi sfugge...
stringitem come settext accetta solo una String.. :mbe:
ma comunque, ho visto ora che si tratta di un gioco, quindi immagino che starai usando una canvas..
non potresti semplicemente crearti dei font e disegnarli sulla canvas in modo da rappresentare i secondi?
in pratica avresti solo 10 oggetti che rappresentano le cifre da 0 a 9 e che vengono disegnati sullo schermo....
magari la cosa ideale, o meglio, la prima cosa ideale che mi viene in mente è di crearti una copia di ogni cifra per ogni posizione numerica da visualizzare..
ad esempio se devi plottare un numero di secondi di tre cifre con due decimali ti crei una matrice 5 X 10 in cui memorizzi le varie cifre e le prendi da là per aggiornare la canvas.
In questo modo puoi plottare fino a 999 secondi semplicemente utilizzando 50 oggetti.
questo sempre nel caso che plottare lo steso oggetto sulla canvas ti possa dare qualche problema che ora sinceramente mi sfugge...
tutto questo sempre in teoria perchè non mi ricordo che minghia succede sulla canvas quando fai ridisegnare un oggetto se fa porcherie..
ultimamente sto lavorando solo con i video-player e quelli mi sembrano abbastanza stabili ad ogni redraw (tenendo conto che sono 10 fps a 320 X 240 mi pare un buon risultato anche...)
No il gioco è quello che feci quasi 3 anni fa in java.
Ora si tratta di un cronometro per cellulari, e sto già utilizzando un array di immagini per le cifre(da 0 a 9) per ore,minuti,secondi e centesimi e non ho problemi di memoria.
In realtà non ho capito perchè useresti una matrice, basterebbe usare 10 char, uno per ogni cifra, e metterli in un array ordinato.
Poi con poche operazini si ricavavano unità,decine,centinaia ecc ecc da stampare.
Mi interessava però sapere se con le stringhe c'era un metodo alternativo.
^TiGeRShArK^
04-03-2009, 02:38
No il gioco è quello che feci quasi 3 anni fa in java.
Ora si tratta di un cronometro per cellulari, e sto già utilizzando un array di immagini per le cifre(da 0 a 9) per ore,minuti,secondi e centesimi e non ho problemi di memoria.
In realtà non ho capito perchè useresti una matrice, basterebbe usare 10 char, uno per ogni cifra, e metterli in un array ordinato.
Poi con poche operazini si ricavavano unità,decine,centinaia ecc ecc da stampare.
Mi interessava però sapere se con le stringhe c'era un metodo alternativo.
no,devi sempre usare una stringa per ogni cifra mi sa da associare a varie label...
dicevo della matrice perchè non mi ricordavo assolutamente se era possibile utilizzare gli stessi oggetti in + punti della canvas senza problemi....ma ad occhio pensandoci direi di si...
Certo che c'è, specialmente coi cellulari, che montano CPU abbastanza limitate.
In questi casi cerca di usare il più piccolo tipo che riesce a rappresentare le quantità che manipoli.
Ma non ti fidare delle cose che ti potrebbero sembrare ovvie. A volte non non lo sono proprio. Ad esempio su alcuni cellulari il tipo boolean occupa 32 bit, cioé 4 byte; molto meglio, in questo caso, farne a meno e utilizzare un byte.
Quindi scrivi un'applicazione di test che ti tiri fuori tutte le informazioni di basso livello che ti servono: dimensione dei tipi standard, delle strighe che manipoli e delle istanze delle classi.
A proposito di classi: già la sola loro definizione (quindi senza nemmeno un'istanza creata) occupa spazio (su alcuni cellurari addirittura 500 byte circa, se non ricordo male), per cui cerca di usare meno classi possibili.
Inoltre utilizza quanto più possibile variabili e metodi static / final.
Esistono altri trucchetti per accelerare l'esecuzione dei cicli, ma sono troppo sporchi, per cui preferisco evitare di parlarne.
Interessante...dai parla dei trucchetti dai dai
cdimauro
04-03-2009, 12:41
Per adesso utilizza le informazioni che t'ho passato. Poi se hai ancora problemi di prestazioni, fammi sapere che ne parliamo. Ma al momento preferirei lasciar perdere. :fagiano:
banryu79
04-03-2009, 13:36
Visto che ti sei creato un array di immagini per le 10 cifre (0-9) fai la stessa cosa per le String: un array di String che rappresenta tutte e 10 le stringhe delle cifre ("0" ... "9").
Alla fine come accedi all'array di immagini tramite indice, così recuperi la corretta String della cifra che ti serve: in questo modo crei solo 10 String.
Dico bene o mi è sfuggito qualcosa?
^TiGeRShArK^
04-03-2009, 14:32
Visto che ti sei creato un array di immagini per le 10 cifre (0-9) fai la stessa cosa per le String: un array di String che rappresenta tutte e 10 le stringhe delle cifre ("0" ... "9").
Alla fine come accedi all'array di immagini tramite indice, così recuperi la corretta String della cifra che ti serve: in questo modo crei solo 10 String.
Dico bene o mi è sfuggito qualcosa?
è esattamente quello che gli ho suggerito io... solo che non ha risposto poi... :stordita:
banryu79
04-03-2009, 15:29
è esattamente quello che gli ho suggerito io... solo che non ha risposto poi... :stordita:
Scusa, sì hai ragione, avevo letto frettolosamente i post e non l'avevo capito.
si ragazzi ho capito, un array di char o una stringa con 10 cifre è praticamente la stessa cosa, volevo sapere se c'era un metodo alternativo.
Comunque non era così importante :p
edit:ah no spe, te dici di fare un array con 10 String, questo mi sembra inutile perchè useresti una Stringa come un char
Per adesso utilizza le informazioni che t'ho passato. Poi se hai ancora problemi di prestazioni, fammi sapere che ne parliamo. Ma al momento preferirei lasciar perdere. :fagiano:
Scusami, per ridurre il numero delle classi intendi che è lecito scrivere codice duplicato anche?
cdimauro
05-03-2009, 08:22
Diciamo che una classe la dovresti usare per implementare più funzionalità, se possibile.
Ad esempio anziché avere una classe Sprite da cui discendono n classi, una per ogni tipologia di oggetto "che si sposta", crei pochi discendenti che trattano quanti più casi possibili.
banryu79
05-03-2009, 10:02
edit:ah no spe, te dici di fare un array con 10 String, questo mi sembra inutile perchè useresti una Stringa come un char
E' no che non è inutile! :)
E' proprio "il trucco" che volevi [sempre se ho capito il tuo problema].
Devi visualizzare il tempo a video; per fare questo usi immagini: una per ogni cifra [0...9] e stampi (per esempio) 6 immagini: 2 per le ore, 2 per i minuti, 2 per i secondi;
Se poi ti serve anche stampare da qualche parte il tempo corrente rappresentato come una String [per esempio in un oggetto Graphics] (ed è questo che non sono sicuro di aver capito bene) invece di creare vagonate di oggetti String (uno ad ogni ciclo) e stamparli usi la tecnica di cui sopra:
una String per ogni cifra [0...9] e a ogni cilco stampi in 6 punti le String cifre: 2 String per le ore, 2 String per i minuti, 2 String per i secondi ecc...
Questo evita che a ogni cilco venga creata una String, rispetto a prima che ne veniva creata sempre una di nuova.
@EDIT
ed è un po' più comodo dell'array di char: che tanto poi li devi trasformare/verranno trasformati in String per essere usati dai compunenti grafici, non è così?
Diciamo che una classe la dovresti usare per implementare più funzionalità, se possibile.
Ad esempio anziché avere una classe Sprite da cui discendono n classi, una per ogni tipologia di oggetto "che si sposta", crei pochi discendenti che trattano quanti più casi possibili.
Ah ok perfetto capito.
E' no che non è inutile! :)
E' proprio "il trucco" che volevi [sempre se ho capito il tuo problema].
Devi visualizzare il tempo a video; per fare questo usi immagini: una per ogni cifra [0...9] e stampi (per esempio) 6 immagini: 2 per le ore, 2 per i minuti, 2 per i secondi;
Se poi ti serve anche stampare da qualche parte il tempo corrente rappresentato come una String [per esempio in un oggetto Graphics] (ed è questo che non sono sicuro di aver capito bene) invece di creare vagonate di oggetti String (uno ad ogni ciclo) e stamparli usi la tecnica di cui sopra:
una String per ogni cifra [0...9] e a ogni cilco stampi in 6 punti le String cifre: 2 String per le ore, 2 String per i minuti, 2 String per i secondi ecc...
Questo evita che a ogni cilco venga creata una String, rispetto a prima che ne veniva creata sempre una di nuova.
@EDIT
ed è un po' più comodo dell'array di char: che tanto poi li devi trasformare/verranno trasformati in String per essere usati dai compunenti grafici, non è così?
Puoi anche disegnare singoli caratteri con g.drawChars usando opportunamente offset e length, per questo mi sembrava inutile usare una String per un carattere e basta. :p
banryu79
05-03-2009, 12:55
g.drawChars
Perdona la mia ignoranza, non lo sapevo :)
Certo che c'è, specialmente coi cellulari, che montano CPU abbastanza limitate.
In questi casi cerca di usare il più piccolo tipo che riesce a rappresentare le quantità che manipoli.
Ma non ti fidare delle cose che ti potrebbero sembrare ovvie. A volte non non lo sono proprio. Ad esempio su alcuni cellulari il tipo boolean occupa 32 bit, cioé 4 byte; molto meglio, in questo caso, farne a meno e utilizzare un byte.
Quindi scrivi un'applicazione di test che ti tiri fuori tutte le informazioni di basso livello che ti servono: dimensione dei tipi standard, delle strighe che manipoli e delle istanze delle classi.
A proposito di classi: già la sola loro definizione (quindi senza nemmeno un'istanza creata) occupa spazio (su alcuni cellurari addirittura 500 byte circa, se non ricordo male), per cui cerca di usare meno classi possibili.
Inoltre utilizza quanto più possibile variabili e metodi static / final.
Esistono altri trucchetti per accelerare l'esecuzione dei cicli, ma sono troppo sporchi, per cui preferisco evitare di parlarne.
Volevo chiederti una cosa, se uso come argomento un byte in un metodo che accetta un int, immagino che viene automaticamente fatto un cast, questa operazione spreca risorse?
Visto che java non ha i pimitivi unsigned, posso usare un char come fosse un unsigned short senza problemi?
cdimauro
06-03-2009, 21:13
Volevo chiederti una cosa, se uso come argomento un byte in un metodo che accetta un int, immagino che viene automaticamente fatto un cast, questa operazione spreca risorse?
Sì, per lo meno l'istruzione (o istruzioni) per "estendere" il byte a int.
Visto che java non ha i pimitivi unsigned, posso usare un char come fosse un unsigned short senza problemi?
Francamente non ricordo bene i limiti dei tipi di Java.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.