Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2005

Tip: Looking for answers? Try searching our database.

ObjectOutputStream doesn't free memory with reset()

Thread view: 
matabasco@gmail.com - 24 Oct 2005 17:02 GMT
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



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.