Failure to free Java resources
When you create a Java™ object
by calling a constructor, or by calling a method that returns an object,
that object will remain in existence until it is freed. It is freed
when:
- The RPG program calls a JNI function to free the object (see Additional RPG Coding for Using Java).
- When the native method returns, if the object was created during a call from Java to a native method.
- When the JVM ends.
If the RPG procedure calling the Java method is not itself an RPG native method, and the RPG procedure does not take care to free objects it has created, then the job may eventually be unable to create any more objects.
Consider the following code fragment:
strObject = newString ('abcde');
strObject = trim (strObject);
data = getBytes (strObject);
freeLocalRef (strObject);
It appears that this code is taking care to free the object, but
in fact this code creates two objects. The first object is created
by the called to newString(), and the second is created by the call
to trim(). Here are two ways to correct this code fragment:
- By freeing several objects at once:
beginObjGroup(); strObject = newString ('abcde'); strObject = trim (strObject); data = getBytes (strObject); endObjGroup(); - By keeping track of all objects used, and freeing them individually:
strObject = newString ('abcde'); trimmedStrObject = trim (strObject); data = getBytes (trimmedStrObject); freeLocalRef (strObject); freeLocalRef (trimmedStrObject);
Another problem can be created by calling Java methods as parameters to other Java methods. In the following example, the
program is creating a BigDecimal object from the constructor that
takes a String parameter:
bigDec = newBigDecimal (newString ('12.345'));
…
freeLocalRef (bigDec);
The problem with this code is that a String object has been created
for the parameter, but it can never be freed by the RPG procedure.
This problem can be corrected by calling beginObjGroup() before
the RPG code that calls Java and
calling endObjGroup() after, or by coding as follows:
tempObj = newString ('12.2345');
bigDec = newBigDecimal (tempObj);
freeLocalRef (tempObj);
…
freeLocalRef (bigDec);