/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Dekonstruktor i Java ?
Fra : Søren Sømand


Dato : 12-10-03 09:03

Hey NG!
Jeg arbejder på Legos Mindstorm, hvor der jo er meget begrænset med plads.
Jeg har derfor et problem med at finde en måde at nedlægge objekter, da jeg
ikke har adgang til Garbage Collectoren. I C++ ville jeg have lavet en
dekonstruktor, men hvad gør man i Java ?
Mvh.
Søren Søpølse



 
 
Bertel Lund Hansen (12-10-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 12-10-03 11:18

Søren Sømand skrev:

>Jeg arbejder på Legos Mindstorm

Det er da rart at se at du ikke er blevet fyret siden i går.

--
Bertel
http://bertel.lundhansen.dk/   FIDUSO: http://fiduso.dk/

Trygleren [9000] (12-10-2003)
Kommentar
Fra : Trygleren [9000]


Dato : 12-10-03 22:10

> >Jeg arbejder på Legos Mindstorm
> Det er da rart at se at du ikke er blevet fyret siden i går.

Hehe =)

--
"Sic gorgiamus allos subjectatos nunc"
Lars 'Trygleren' Winther
www.hesteskelet.dk <-- Grøntfoder obligatorisk!



Michael Berg (29-10-2003)
Kommentar
Fra : Michael Berg


Dato : 29-10-03 23:32

Hej Søren Sømand - og tak for den gode pålægschokolade iøvrigt ...

> Jeg arbejder på Legos Mindstorm, hvor der jo er meget begrænset med plads.
> Jeg har derfor et problem med at finde en måde at nedlægge objekter, da
jeg
> ikke har adgang til Garbage Collectoren. I C++ ville jeg have lavet en

Java sørger selv for at opsamle døde referencer og lægge dem på GC stakken.
Den rydder den så periodisk op i - det er egentlig ikke noget du skal tænke
på.

Du kan ikke fremtvinge en garbage collection, men du kan opfordre JVM'en til
det ved at kalde metoden:

System.gc();

Hvis du iterativt løber en lang liste igennem kan du fx. kalde gc() efter
løkken. På den måde får du måske lidt ekstra luft på et tidspunkt som JVM'en
ikke selv havde kunnet gætte.

> dekonstruktor, men hvad gør man i Java ?

Der findes ingen destructor i Java, men der findes en metode i Object
klassen ved navn finalize(), som du har mulighed for at overstyre. Garbage
collectoren kalder metoden som en del af oprydningsprocessen (dvs. når den
engang synes den har tid og lyst til det), og her har du mulighed for at
frigive "eksterne" ressourcer du måtte have allokeret engang i objektets
levetid (måske noget DLL sjov, JNI, fil-låsning, RMI eller Corba kald for at
rydde op i nogle referencer på en server et sted - hvad ved jeg).

Bemærk at det er garbage collectoren der kalder finalize(). Du skal (må)
ikke selv kalde metoden. Lotus Notes arbejder af samme årsag med en
recycle() metode på alle objekter, netop for explicit at kunne frigive
eksterne ressourcer uden at være afhængig af garbage collectoren. Det er
ikke nogen køn løsning men det virker da.

Mvh Michael
www.hyperpal.com
Home of Favorites

> Mvh.
> Søren Søpølse
>
>


Troels Arvin (30-10-2003)
Kommentar
Fra : Troels Arvin


Dato : 30-10-03 10:43

On Wed, 29 Oct 2003 23:31:43 +0100, Michael Berg wrote:

> Bemærk at det er garbage collectoren der kalder finalize().
> Du skal (må) ikke selv kalde metoden.

Hvor "står" det egentlig - altså at man ikke manuelt må kalde
finalize()? Hvilke problemer opstår ved at kalde den manuelt, fx. inden
objektreferencen sættes til null?

Jeg synes, at det er en ubetagelig gotcha ved Java, at man ikke kan være
sikker på, at finalize() bliver kaldt. Se fx. følgende program. Efter
afvikling findes hos mig 28 filer tilbage i "testdir" kataloget, med
mindre jeg tilføjer System.gc() kaldet.

Er der nogen, der kender til baggrunden for, at garbage-collector ikke
per default køres til ende ved programafvikling? - Det burde vel
sjældent være det store problem, hvis program-afvikling tager et par
sekunder.

// ---------------- FileOpener.java ---------------------
// Afvikling kræver, at underkataloget "testdir" findes
import java.io.*;

public class FileOpener {
String fname;
FileWriter file;

public FileOpener(String name) throws Exception {
fname=name;
file = new FileWriter(name);
System.out.println("Created file with name "+name);
}

public void finalize() throws Exception {
file.close();
new File(fname).delete();
System.out.println("Closed and removed file with name "+fname);
}

public static void main(String[] args) throws Exception {
for (int i=0; i<10000; i++) {
String n="testdir/j"+i;
FileOpener f = new FileOpener(n);
f = null;
}
// System.gc(); // hvis denne udkommenteres, ryddes der
// tilsyneladende ordentligt op hver gang
}
}
// ------------------------------------------------------

--
Greetings from Troels Arvin, Copenhagen, Denmark


Filip Larsen (30-10-2003)
Kommentar
Fra : Filip Larsen


Dato : 30-10-03 12:30

Troels Arvin skrev

> Hvor "står" det egentlig - altså at man ikke manuelt må kalde
> finalize()? Hvilke problemer opstår ved at kalde den manuelt, fx. inden
> objektreferencen sættes til null?

Der er mig bekendt ikke noget i specifikation af Java der siger man ikke må
selv må kalde finalize hvis man absolut gerne vil. Faktisk står der i Java
Language Specifiation, afsnit 12.6: "A finalizer may be invoked explicitly,
just like any other method." Bruger man finalizer er det dog op til en selv
at kode den så den opfører sig korrekt selvom den bliver kaldt flere gange,
hvad enten det så er garbage collectoren eller programmet selv der kalder.

Læs selv mere om finalizers i JLS:
http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44760


> Jeg synes, at det er en ubetagelig gotcha ved Java, at man ikke kan være
> sikker på, at finalize() bliver kaldt. Se fx. følgende program. Efter
> afvikling findes hos mig 28 filer tilbage i "testdir" kataloget, med
> mindre jeg tilføjer System.gc() kaldet.

Finalize mekanismen har den uheldige egenskab, at folk ofte misforstår dens
anvendelse og bruger den som destructor i stedet, ofte med skuffende
resultat. Garbage collection er grundlæggende set en ikke deterministisk
process i Java der bruges til at genskabe ledig plads på heapen, så kald til
finalize er grundlæggende set også ikke-deterministisk.

Selvom der i dokumentationen for finalize står, at finalize kan bruges til
management af externe resourcer, så tror jeg man gør sig selv en tjeneste
ved som tommefingerregel aldrig at bruge finalize til dette, hvilket mig
bekendt også er den praksis Sun selv anbefaler. I stedet kan man (i Java
1.3+) lave en resource manager der benytter svage referencer og en shutdown
hook (Runtime.addShutdownHook), eller man kan benytte de oprydnings metoder
der allerede måtte være i de forskellige API'er.

I den kode du angiver kan du fx. benytte File.deleteOnExit et passende sted
under initializing af hver fil og så helt droppe finalize metoden og kaldet
til System.gc().


> Er der nogen, der kender til baggrunden for, at garbage-collector ikke
> per default køres til ende ved programafvikling? - Det burde vel
> sjældent være det store problem, hvis program-afvikling tager et par
> sekunder.

Med Runtime.runFinalizersOnExit (der nu er deprecated) kan man faktisk godt
bede JVM'en om at køre GC inden den afslutter, men som sagt bør ens kode
ikke være afhængig af dette. Faktisk burde det være sådan, at koden i
princippet også virker hvis den køres på en JVM med "uendelig" heap uden
garbage collection.


Mvh,
--
Filip Larsen



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste