ObjectOutputStream doesn't free memory with reset()

M

matabasco

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);

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.substring(sElegidos.lastIndexOf("\\") +
1,sElegidos.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.
 
G

Gordon Beaton

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.

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
 
M

matabasco

'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.
 
M

Monique Y. Mudama

'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.
 
M

matabasco

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.
 
J

John C. Bollinger

Monique said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top