Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force explicit deletion of a Java object

I'm working on a Java server that handles a LOT of very dense traffic. The server accepts packets from clients (often many megabytes) and forwards them to other clients. The server never explicitly stores any of the incoming/outgoing packets. Yet the server continually runs into OutOfMemoryException exceptions.

I added System.gc() into the message passing component of the server, hoping that memory would be freed. Additionally, I set the heap size of the JVM to a gigabyte. I'm still getting just as many exceptions.

So my question is this: how can I make sure that the megabyte messages aren't being queued indefinitely (despite not being needed)? Is there a way for me to call "delete" on these objects to guarantee they are not using my heap space?

        try
        {
           while (true)
            {
               int r = generator.nextInt(100);//generate a random number between 0 and 100
                Object o =readFromServer.readObject();
                sum++;
                // if the random number is larger than the drop rate, send the object to client, else
                //it will be dropped
                if (r > dropRate)
                {
                    writeToClient.writeObject(o);
                    writeToClient.flush();
                    numOfSend++;
                    System.out.printf("No. %d send\n",sum);
                }//if

            }//while
        }//try
like image 510
Curious George Avatar asked Feb 01 '10 16:02

Curious George


People also ask

Can we explicitly destroy objects in Java?

Java doesn't let you destroy objects. Any unreachable object may (or may not) be GCed at any particular point in time.

How do you completely remove an object in Java?

The remove(Object obj) method of List interface in Java is used to remove the first occurrence of the specified element obj from this List if it is present in the List. Parameters: It accepts a single parameter obj of List type which represents the element to be removed from the given List.

How can we delete a dog object in Java?

When you set dog to null in deleteObject the dog reference in main is still pointing to the object. You can just set the dog reference to null in main and this will make the object elligible for garbage collection.

How do you make an object delete itself?

To "clear" the object within itself one would just clear all instance variables. To "clear" the object outside itself one would set the variable equal to null.


2 Answers

Object streams hold references to every object written/read from them. This is because the serialization protocol allows back references to objects that appeared earlier in the stream. You might be able to still use this design but use writeUnshared/readUnshared instead of writeObject/readObject. I think, but am not sure, that this will prevent the streams from keeping a reference to the object.

As Cowan says, the reset() method is also in play here. The safest thing to do is probably use writeUnshared immediately followed by reset() when writing to your ObjectOutputStreams

like image 141
Geoff Reedy Avatar answered Nov 15 '22 16:11

Geoff Reedy


When JVM is on an edge of OutOfMemoryError, it will run the GC.

So calling System.gc() yourself beforehand ain't going to fix the problem. The problem is to be fixed somewhere else. There are basically two ways:

  1. Write memory efficient code and/or fix memory leaks in your code.
  2. Give JVM more memory.

Using a Java Profiler may give a lot of information about memory usage and potential memory leaks.

Update: as per your edit with more information about the code causing this problem, have a look at Geoff Reedy's answer in this topic which suggests to use ObjectInputStream#readUnshared() and ObjectOutputStream#writeUnshared() instead. The (linked) Javadocs also explains it pretty well.

like image 20
BalusC Avatar answered Nov 15 '22 16:11

BalusC