付録A Javaヒープメモリのリークを起こしやすいJavaAPIクラス

JavaAPIクラスを使用した場合,JavaAPIクラスのインスタンスがJavaヒープメモリ上に作成されます。しかし,表A-1および表A-2に示すJavaAPIクラスのメソッドを使用して,表の条件に該当する場合,JavaAPIクラス以外のインスタンスもJavaヒープメモリ上に作成されます。

作成されたユーザ作成クラスのインスタンスは,JavaAPIクラスが削除されるまでJavaヒープメモリ上に残ります。このため,ユーザが意識しない間にJavaヒープメモリの使用量が増え,Javaヒープメモリがリークするおそれがあるので注意してください。

ただし,表A-2のJavaAPIクラスについては,ユーザ作成クラスのインスタンスを削除することもできます。

Javaヒープメモリがリークしやすいクラス一覧について,インスタンスの削除方法がある場合とない場合に分けて表に示します。表A-2については,ユーザ作成のインスタンスの削除方法も示します。

参考
Javaヒープメモリのリークを起こしやすいJavaAPIクラスや条件,およびユーザ作成クラスのインスタンス削除方法については,08-00以降変更される場合があります。

 

表A-1 Javaヒープメモリがリークしやすいクラス一覧(削除方法がない場合)

JavaAPIクラス名Javaヒープメモリにユーザ作成クラスのインスタンスを作成する条件
java.lang.ClassLoaderdefineClass()メソッドの引数に指定したProtectionDomainがユーザ作成クラスと関連づけられている場合。
java.net.URLURLクラスインスタンスを生成する際,URLStreamHandlerFactoryが作成するURLStreamHanderクラスがユーザ作成クラスの場合。
java.text.DateFormatDateFormatクラスを継承したユーザ作成クラスのコンストラクタでsuper()を呼び出した場合。
java.util.logging.LevelLevelクラスを継承したユーザ作成クラスのコンストラクタでsuper()を呼び出した場合。
java.util.logging.LogManageraddLogger()メソッドの引数にLoggerクラスを継承したユーザ作成クラスを指定した場合。
java.util.logging.LoggerLoggerクラスを継承したユーザ作成クラスでgetAnonymousLogger()メソッドや setParent()メソッドを呼び出した場合。
javax.accessibility.AccessibleBundletoDisplayString()メソッドの引数に指定したリソースバンドル名に対応するユーザ実装のクラスで,そのユーザ実装のクラス内で保持しておくキーと値のペアの値に,ユーザクラスのオブジェクトを設定している場合。
javax.print.attribute.standard.MediaSizeMediaSizeクラスを継承したユーザ作成クラスのコンストラクタでsuper()を呼び出した場合。
java.rmi.server.UnicastRemoteObjectexportObject()メソッドの引数(RMIClientSocketFactory,RMIServerSocketFactory)にユーザ作成クラスを指定した場合。

表A-2 Javaヒープメモリがリークしやすいクラス一覧(削除方法がある場合)

JavaAPIクラス名Javaヒープメモリにユーザ作成クラスのインスタンスを作成する条件ユーザ作成クラスのインスタンス削除方法
java.beans.IntrospectorgetBeanInfo()メソッドの引数(beanClass)にユーザ作成クラスを指定した場合。flushCaches()メソッドやflushFromCaches()メソッドを実行する。
java.beans.PropertyEditorManagerregisterEditor()メソッドの引数(editorClass)にユーザ作成クラスを指定した場合。registerEditor()メソッドのeditorClassにnullを指定する。
java.util.logging.LoggeraddHandler()メソッドの引数にHandlerクラスを継承したユーザ作成クラスを指定した場合。removeHandler()メソッドを実行する。
javax.imageio.ImageReaderaddIIOReadWarningListener()メソッドの引数にIIOReadWarningListenerクラスを継承したユーザ作成クラスを指定した場合。removeIIOReadWarningListener()メソッドを実行する。
addIIOReadProgressListener()メソッドの引数にIIOReadProgressListenerクラスを継承したユーザ作成クラスを指定した場合。removeIIOReadProgressListener()メソッドを実行する。
addIIOReadUpdateListener()メソッドの引数にIIOReadUpdateListenerクラスを継承したユーザ作成クラスを指定した場合。removeIIOReadUpdateListener()メソッドを実行する。
javax.imageio.ImageWriteraddIIOWriteProgressListener()メソッドの引数にIIOWriteProgressListenerクラスを継承したユーザ作成クラスを指定した場合。removeIIOWriteProgressListener()メソッドを実行する。
addIIOWriteWarningListener()メソッドの引数にIIOWriteWarningListenerクラスを継承したユーザ作成クラスを指定した場合。removeIIOWriteWarningListener()メソッドを実行する。
javax.naming.InitialContextaddToEnvironment()メソッドの引数(propVal)にユーザ作成クラスを指定した場合。removeFromEnvironment()メソッドを実行する。
javax.naming.spi.NamingManagergetContinuationContext()メソッドの引数にユーザ作成クラスを指定した場合。得られたContextのclose()を実装してsuper()を実行する。
javax.print.attribute.HashAttributeSetadd()メソッドの引数にユーザ作成クラスを指定した場合。remove(Attribute)メソッドや remove(Class)メソッドを実行する。