Hi everybody:
I'm deveoping an applet that lets users to select files from an
explorer view, and copies them to a remote machine in a specified path.
The program works well, but the problem is when it copies a few files,
the memory grows and grows up (ever when the files have a length not
very bigger).
I read in the web and groups about use the method reset (from
ObjectOutputStream) after all the objects where sent, but it seems (in
this case) it doesn't work.
'could anyone help me or tell me an alternative method to do this??
This is the code I'm using:
In the applet side (send files):--------------------------------
ObjectOutputStream oos = null;
try {
URLConnection urlConnection = getUrlConnectionServ();
if(urlConnection != null) {
oos = new ObjectOutputStream(urlConnection.getOutputStream());
String sUnidad = (String) getJComboBox().getSelectedItem();
String sFichero;
Object[] oRuta;
Vector vFicheros = new Vector();
Vector vDescFich;
File fFich;
FileInputStream fis;
byte bain[];
getJProgressBar1().setVisible(true);
ByteArrayOutputStream baos = null;
for (int i = 0; i < sElegidos.length; i++) {
fFich = new File(sElegidos[i]);
if (!fFich.isDirectory()) {
baos = new ByteArrayOutputStream();
fis = new FileInputStream(fFich);
bain = new byte[(int)fFich.length()];
byte[] bBuffer = new byte[131072];
int offset = 0;
int numRead = 0;
int iTotalLeidos = 0;
while(offset < bain.length && (numRead=fis.read(bBuffer,
offset, bain.length-offset)) >= 0) {
baos.write(bBuffer, 0, numRead);
Thread.sleep(40);
}
vDescFich = new Vector(2);
vDescFich.addElement(new
String(sElegidos[i].substring(sElegidos[i].lastIndexOf("\\") +
1,sElegidos[i].length())));
vDescFich.addElement(new
Long(fFich.lastModified()).toString());
//vDescFich.addElement(bain);
vDescFich.addElement(baos.toByteArray());
vFicheros.addElement(vDescFich);
fis.close();
}
}
oos.writeObject(new String("EnviarFicheros"));
oos.writeObject(getMFichRemotos().getSRutaRemota());
oos.writeObject(vFicheros);
oos.reset();
oos.close();
oos = null;
} else {
throw new Exception("No se pudo realizar la conexión.");
}
}
In the servlet side (recieves files):
private void enviarFicheros(String sRutaDestino, Vector vFicheros,
javax.servlet.http.HttpServletResponse res) {
int iBuffer = 2048;
try {
File fFich;
File fFichAux;
FileInputStream fis;
FileOutputStream fos;
ByteArrayInputStream bais;
byte[] bDatosFich;
String sNombreFichero = null;
byte buffer[] = new byte[iBuffer];
Runtime rtJava = null;
File fDir = new File(sRutaDestino);
for (int i = 0; i < vFicheros.size(); i++) {
sNombreFichero = (String) ((Vector)
vFicheros.elementAt(i)).elementAt(0);
fFichAux = new File(sRutaDestino, sNombreFichero);
fFichAux.setLastModified(Long.parseLong((String)((Vector)
vFicheros.elementAt(i)).elementAt(1)));
fos = new FileOutputStream(fFichAux);
bDatosFich = (byte[]) ((Vector)
vFicheros.elementAt(i)).elementAt(2);
bais = new ByteArrayInputStream(bDatosFich);
fos.write(bDatosFich);
fos.flush();
fos.close();
bais.close();
if (!System.getProperty("os.name").startsWith("Windows")) {
rtJava = Runtime.getRuntime();
rtJava.exec("chown gescom2:gescom " + sRutaDestino +
sNombreFichero);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Thank you very much,
Marco Tabasco.
Gordon Beaton - 25 Oct 2005 10:43 GMT
> I'm deveoping an applet that lets users to select files from an
> explorer view, and copies them to a remote machine in a specified path.
[quoted text clipped - 6 lines]
> ObjectOutputStream) after all the objects where sent, but it seems
> (in this case) it doesn't work.
Reset is used to clear the Object cache used by the
ObjectOutputStream, and it does that. However the garbage collector
needs to run before the memory is reclaimed, and you have no control
over that.
ObjectOutputStream is the wrong stream type for sending files. Use a
"regular" OutputStream instead (or a BufferedOutputStream).
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
matabasco@gmail.com - 25 Oct 2005 14:33 GMT
'where must I include a call to gc?? I've tried this:
Runtime.getRuntime().gc();
oos.writeObject(new String("EnviarFicheros"));
oos.writeObject(getMFichRemotos().getSRutaRemota());
oos.writeObject(vFicheros);
oos.reset();
oos.close();
oos = null;
but it still happens the same.
I use ObjectOutputStream because I send Vector objects with metainfo of
the files...but I will consider your suggestion about using
OutpuStream.
Thank you for your responses.
Marco.
Roedy Green - 25 Oct 2005 14:50 GMT
> 'where must I include a call to gc?? I've tried this:
It is never required. It can be placed anywhere. Usually it will be
ignored.

Signature
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.
Monique Y. Mudama - 25 Oct 2005 20:58 GMT
> 'where must I include a call to gc?? I've tried this:
>
> Runtime.getRuntime().gc();
I just noticed that the javadocs claim that this runs the garbage
collector. But that's not actually true.
This is a request, maybe a hint, to the JVM to call the GC. The JVM
can (and often will) ignore it.
There's no way to force garbage collection to happen.

Signature
monique
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
matabasco@gmail.com - 26 Oct 2005 08:48 GMT
So...'any other method to free memory or to send files though network
without the memory costs of using ObjectOutputStream with Vector
objects??
I've tried to send with primary types (writeChars() for sending
Strings, write() for sending bytes[]), but it seems still catch more
memory than expected.
Thanks to all!!
Marco.
John C. Bollinger - 28 Oct 2005 04:43 GMT
>> 'where must I include a call to gc?? I've tried this:
>>
>> Runtime.getRuntime().gc();
>
> I just noticed that the javadocs claim that this runs the garbage
> collector.
Sort of. The byline says that, but if you actually read the method docs
it says this: "Calling this method *suggests* that the Java virtual
machine expend effort toward recycling unused objects [...]" (emphasis
mine).
> But that's not actually true.
>
> This is a request, maybe a hint, to the JVM to call the GC. The JVM
> can (and often will) ignore it.
You're right. Moreover, and possibly relevant to the OP, freeing heap
memory does not equate to returning memory to the OS. That indeed may
or may not happen as a result of GC, depending on the VM implementation
among many other things.

Signature
John Bollinger
jobollin@indiana.edu