Java リソースの解放エラー
コンストラクターを呼び出すことで、
またはオブジェクトを戻すメソッドを呼び出すことで、Java™ オブジェクトを作成した場合、
作成したオブジェクトは解放しない限り存在し続けます。オブジェクトが解放されるのは次の場合です。
- RPG プログラムが、オブジェクトを解放する JNI 関数を呼び出したとき (Java を使用するためのその他の RPG コーディングを参照)。
- Java から固有メソッドへの呼び出し中にオブジェクトが作成された場合に固有メソッドが返されたとき。
- JVM が終了したとき。
Java メソッドを呼び出す RPG プロシージャーが RPG 固有のメソッドではない場合、 および RPG プロシージャーが、自分が作成したオブジェクトの解放に責任を持たない場合、 そのジョブは結果的にそれ以上オブジェクトを作成できなくなる可能性があります。
次のようなコード・フラグメントがあるとします。
strObject = newString ('abcde');
strObject = trim (strObject);
data = getBytes (strObject);
freeLocalRef (strObject);
このコードはオブジェクトの解放を引き受けているようですが、
実際にはこのコードは 2 つのオブジェクトを作成します。
1 つ目のオブジェクトは newString() 呼び出しによって作成され、
2 つ目のオブジェクトは trim() 呼び出しによって作成されます。
このコード・フラグメントを訂正するには、以下の 2 つの方法があります。
- 複数のオブジェクトを同時に解放:
beginObjGroup(); strObject = newString ('abcde'); strObject = trim (strObject); data = getBytes (strObject); endObjGroup(); - 使用されているオブジェクトすべてを追跡し、それらを個別に解放:
strObject = newString ('abcde'); trimmedStrObject = trim (strObject); data = getBytes (trimmedStrObject); freeLocalRef (strObject); freeLocalRef (trimmedStrObject);
Java メソッドをほかの Java メソッドのパラメーターとして呼び出すと、
別の問題が起こることがあります。次の例では、String パラメーターを取るコンストラクターから
BigDecimal オブジェクトを作成しています。
bigDec = newBigDecimal (newString ('12.345'));
…
freeLocalRef (bigDec);
このコードの問題は、パラメーターの指定により String オブジェクトが作成されたのに、
RPG プロシージャーはこのオブジェクトを解放できないことです。
この問題を訂正するには、Java を呼び出す RPG コードの前に beginObjGroup() を呼び出し、
後で endObjGroup() を呼び出すか、以下のようにコーディングします。
tempObj = newString ('12.2345');
bigDec = newBigDecimal (tempObj);
freeLocalRef (tempObj);
…
freeLocalRef (bigDec);