Hejsan! GC ligger inte i bakgrunden och körs hela tiden utan den körs lite då Hej... Tja.Memory leak och lite optimering...
Tänkte för en gång skull ställa en vettig fråga i detta forum ;)
Jag har skrivit en "convinience" klass för att enkelt kunna kopiera hela katalogstrukturer i ett enda metodanrop.
Problemet jag upplever med denna implementation jag gjort är att det går åt väldigt mkt minne i "runtime". Jag sitter på en burk m 384 MB minne och allt blir använt så att swap-filen e tvungen att användas.
Detta är ju inte vad jag vill då det kan orsaka prestandaproblem hos datorer med mindre minne. Här är en bit av koden:
<code>
/**
* Copies a complete directory to a new destination. This method will block until some
* input is available, an I/O error occurs, or the end of the stream is reached.
*
* @param directory the complete File path to the source directory
* @param destination the complete File path to the destination
* @throws FileNotFoundException if the specified file is not found
* @throws IOException if an I/O error occurs
*/
public static void copyDirectory(File directory, File destination) throws FileNotFoundException,
IOException {
if (directory.isDirectory()) {
String list[] = directory.list();
File dest = new File(destination.getPath() + SEPARATOR + directory.getName());
dest.mkdirs();
for (int i = 0; i < list.length; i++) {
copyDirectory(new File(directory, list[i]), new File(destination.getPath()
+ SEPARATOR + directory.getName()));
}
} else if (directory.isFile()) {
copyFile(directory.getPath(),
new File(destination+SEPARATOR+directory.getName()).getPath());
}
}
</code>
..som i sin tur kallar följande metod när den hittar en fil:
<code>
/**
* Copies a file to a new file. This method will block until some input
* is available, an I/O error occurs, or the end of the stream is reached.
*
* @param file the file to copy
* @param newFile the new copied file
* @throws FileNotFoundException if the specified file is not found
* @throws IOException if an I/O error occurs
*/
public static void copyFile(String file, String newFile) throws FileNotFoundException,
IOException {
InputStream fis = new FileInputStream(file);
OutputStream fos = new FileOutputStream(newFile);
byte[] buffer = new byte[BLOCKSIZE];
int read;
while ((read = fis.read(buffer,0,buffer.length)) != -1) {
fos.write(buffer,0,read);
}
fos.close();
fis.close();
}
</code>
Eftersom det endast är lokala variabler som används så borde åtkomsten till objektreferenserna försvinna i och med att man kommer utanför metoden och således bli "garbage collected" på ett bra sätt. Varför upplever jag då denna stora minnesåtgång vid körning av metoden?
/AndreasSv: Memory leak och lite optimering...
och då (vet inte vad det är för intervall eller vad som triggar den), detta
kan göra att ditt program blir lite segt i mellanåt...
Testa att sätta dina lokala varibler till null så länge och se om det kan
hjälpa, kan även hjälpa att deklarara variabler man använder mycket
i klassen och inte metoden och bara skapa instansen i klassen. Kanske
inte så snyggt men om det bara är prestanda du är ute efter kan det
vara värt ett försök.
/EmmaSv: Memory leak och lite optimering...
Jo, jag vet att GC körs lite då och då som en lågprioritets-tråd i JVM i ett visst intervall (beroende på operativsystem, skilland mellan UNIX och Windows) för att rensa bort objekt som inte är refererade längre...
"NULL-metoden" har jag provat och kom på efter ett tag att det inte behövs nullas ngt eftersom objektreferensens accessabilitet försvinner då man kommer ur från metoden, eller hur... ;-)
Och att ha instansvariabler håller jag inte med om att det skulle förbättra ngt, då dessa variabler kommer att hålla objektreferensen i JVM's minne tills programmet (körningen) avslutas (till skillnad från lokala variabler som endast överlever från början till slutet av en metod) vilket blir mindre minne kvar under "runtime"...
Man kan iof föreslå att JVM ska köra GC (System.gc()), men det ger inga garantier då den bara föreslår GC.
Problemet verkar vara ngt annat. Det som kan ta upp minne under körning är när jag listar filer och kataloger, speciellt om det är en katalog med många filer och kataloger. Detta beror ju på att metoden är rekursiv och därför kommer "accessomfånget" inte släppas under rekursiva anrop. Det är isåfall detta som behover att fokuseras på, hur man kan frigöra detta ur minnet då det bara kommer att refereras till en enda gång....
Ngr tips?
/AndreasSv: Memory leak och lite optimering...
Jag kan ha fel men använder inte JVM så mycket minne som den får tillgång till/behöver ? Vad jag menar är att om du skulle sitta på en burk med 128 MB så skulle det inte gå lika fort för att JVM inte får tillgång till lika mycket minne.
Med andra ord: När du kör ett krävande program på en burk med mycket ledigt minne så snor JVM så mycket minne som den får/kan för att klara av sin uppgift så snabbt som möjligt.
Mvh - Peter.