Speeding up reading serialized object from a file
hi all,
Recently I just written this simple program to read and write objects to a single file. Here is the code that i write to rad the object
public synchronized String readObject (String Objuid)
{
try
{
//1.Create a random access file so that we can read the desired objects randomly by using the seek method
RandomAccessFile raf = new RandomAccessFile (fileName,"r");
//2.get the object's size. This 4 line of codes is for retrieveing the object size so that I cancreate a byte array byte [] obj that has the same length as the object size.
int beginIndex = Objuid.indexOf(".");
int uid = Integer.parseInt(Objuid.substring(beginIndex + 1,Objuid.length()));
FileID currentFileId = (FileID)obj.elementAt(uid);
int size = new Long (currentFileId.getSize()).intValue();
byte [] obj = new byte [size];
//3. Read the object. Now to read the object I place the RandomAccessFile pointer to the start byte of the object. After that I read that object using the RandomAccessFile read (byte [] b, start, end) method.
long pointer = currentFileId.getPointer();
raf.seek (pointer);
raf.read(obj,0,size);
//4. To deserialize the object I pass the previous byte array byte [] obj to a ByteArrayInputStream
ByteArrayInputStream inArray = new ByteArrayInputStream (obj);
ObjectInputStream objIn = new ObjectInputStream (new BufferedInputStream(inArray));
String str = objIn.readObject ().toString();
//5.Close all the stream used to read the object
objIn.close();
inArray.close();
raf.close();
obj = null;
System.runFinalization();
System.gc();
return str;
}
catch (Exception err) {
err.printStackTrace();
return "";
}
}
The problem is that if i want to read the objects the memory usage just shoot up and does not get free up. So it take a very long time to output the object content and eats up alot of memory. Is there any way to reduce the memory usage or to make the code more effecient in allocating the memory resources.
I monitor the memory usage by using win2000 performance monitor tool.
Thanks
Hi,
I'm just curious: Why all that effort?
After all, your method just offers one functionality: Get a String from a File where that String was previously saved in serialized form.
Either you're just doing some prototype, finger-exercices, or you missed something.
In the latter case, here's what I mean:
You could use ObjectInputStream and ObjectOutputStream directly for this:
FileInputStream istream = new FileInputStream(fileName);
ObjectInputStream p = new ObjectInputStream(istream);
String str = (String)p.readObject();
istream.close();
return str;
//of course exceptionhandling missing here ;)
This works for all Objects implementing the Serializable (marker) interface. (String does).
But I'm probably barking up the wrong tree anyway... ;)
> Hi,
>
> I'm just curious: Why all that effort?
>
> After all, your method just offers one functionality:
> Get a String from a File where that String was
> previously saved in serialized form.
>
> Either you're just doing some prototype,
> finger-exercices, or you missed something.
>
> In the latter case, here's what I mean:
>
> You could use ObjectInputStream and ObjectOutputStream
> directly for this:
>
> > FileInputStream istream = new
> FileInputStream(fileName);
>
> ObjectInputStream p = new ObjectInputStream(istream);
>
> String str = (String)p.readObject();
> istream.close();
> return str;
> //of course exceptionhandling missing here ;)
>
>
> This works for all Objects implementing the
> Serializable (marker) interface. (String does).
>
> But I'm probably barking up the wrong tree anyway...
> ;)
Hehe perhaps i should state why i do it like this. Let me start from the beginning. First of all i what i want to do is to save multiple objects to a single file. Each object has its own unique id (uid). So the read method here are suppose to be able to read any objects in the file randomly.
That is why my read method has a String parameter called the uid. So whenever i want to read an object I make a call to this method like this e.g. : readObject ("0.2") . So the method identify which object to read by its uid.for the uid i have special naming pattern so it will be easier for me to code the read method, anyway it is not a concern here :) So I use the RandomAccesFile seek method to read each object, and the convert the object into array of bytes.By using ByteArrayInputStream wrapped by the ObjectInputStream the method deserialize the object and get the content.
Hope this make things clearer. Hope you can help me more after I post this explanation Lachp.
= ) inoel131081
Ok, obviously this was NOT a newbie issue ;)
As for the performance/memory problem, I personally would use either the java profiler (java -Xrunhprof, see Tooldoc of java.exe), this will give you hints about which methods use cpu and memory, or a more user-friendly tool like OptimizeIt, which you can download (trial version) at http://www.optimizeit.com/app/download/downloadArea.jsp.
PS:
As for the object-persistence: As far as I can see your 'framework' will have some knowledge about the the objects stored in that file (You'll have some lookup mechanism to match your uid's to data-types, right?). You probably already know, but anyway: One major issue with serialized objects is their version. Each class has a SerialVersionUID, which is either hardcoded in the class or computed dinamically. Now, if you're going for longtime-persistence, there's a risk that the classes may evolve, say new functionality requires new methods etc. Say you have an application that stores objects in some files. 3 Months later, after some classes have been modified, say patched, your running application won't be able to deserialize "MyClass-Version 1" stored Objects to MyClass-Modified-Version" Objects, unless you hardcoded the SerialVersionUID and the class is still compatible.
To make a long story short: I don't know if you're familiar with the problems I mentioned above. Just be alert.
;) Patrick