図1はメモリリーク検出システムの概要構成の一例を示す説明図である。メモリリーク検出システムは、検出装置1、対象装置2を含む。検出装置1及び対象装置2はネットワークNを介して通信を行うことが可能である。対象装置2はテスト対象となるプログラムが動作するコンピュータである。検出装置1は対象装置2に対して、テストの実行を指示したり、メモリ使用量の計測を行わせたりし、その結果の解析を行う。検出装置1は解析結果に基づき、メモリリークが発生していないか否かを判定する。
図2は検出装置1のハードウェアの一構成例を示すブロック図である。検出装置1は、CPU(Central Processing Unit)10、RAM(Random Access Memory)11、ROM(Read Only Memory)12、大容量記憶装置13、入力部14、出力部15、通信部16、読取部17を含む。CPU10はROM12に記憶された制御プログラム1pに従いハードウェア各部を制御する。RAM11は例えばSRAM、DRAM、フラッシュメモリ等である。RAM11はCPU10によるプログラムの実行時に発生する種々のデータを一時的に記憶する。大容量記憶装置13は例えばハードディスク、SSD(Solid State Drive)である。大容量記憶装置13は種々のデータを記憶する。大容量記憶装置13に制御プログラム1pを記憶しておいても良い。入力部14はキーボード、マウス、タッチパネル等であり、ユーザがデータ、コマンドなどを入力する。出力部15は表示装置(図示しない)に表示させるデータを出力する。通信部16はネットワークNを介して、対象装置2、その他のコンピュータと通信する機能を備える。
読取部17はCD(Compact Disk)−ROM、DVD(Digital Versatile Disc)−ROM等の可搬型記憶媒体1bを読み取る。制御プログラム1pは可搬型記憶媒体1bより読取部17が読み取り、大容量記憶装置13に記憶することとしても良い。また、ネットワークNを介して他のコンピュータから制御プログラム1pをダウンロードしても良い。さらにまた、半導体メモリ1aから制御プログラム1pを読み込むこととしても良い。
次に、最初に従来の動作テストにおけるメモリリーク検出方法について説明する。従来の動作テストにおいては、テスト前後でメモリ使用量の変化を観測し、テスト後のメモリ使用量が増大した場合には、同じテスト条件で再テストを行う。再テストにより、メモリ使用量の増大が再現すればメモリリークの可能性有りと判断する。そのような場合は、テスト条件等を変えながらテストを重ねて、メモリリークが発生するかを調査する。再現すればメモリリークが発生していると断定できるが、テストを重ねても再現したり、再現しなかったりする場合には、さらにテスト条件を変えながらテストを行うことになる。このような方法では、飛躍的にテストに要する時間が増大することになる。
一方、メモリ使用量の増大が再現されなければ、テスト対象のプログラムではない他の要因でメモリ使用量が増大したものとして、調査打ち切りとしていた。しかしながら、単に再テストしたのではメモリリークが再現しない場合もあり、調査を打ち切ったことにより、製品出荷後にメモリリークが発見されることになる。
本願発明者は鋭意努力検討した結果、メモリ使用量増大の要因とその増大の再現性との関係に着目して、メモリ使用量の増大現象を分類することにより、無駄な再現テストを重ねることなく、適切なテスト回数でメモリリークを検出可能であることを見出した。以下、順を追って説明する。なお、以下の説明において、障害とは、テスト対象プログラムのメモリリークの他、他の要因でメモリリークが生じたことを言う。タイプとは、メモリ増大現象の類型である。タイプにはメモリリークの障害も含むが、障害とされないものも含む。
次にメモリ増大現象の類型(タイプ)について説明する。以下の説明において参照するグラフは、テストの進行状況とメモリ使用量との関係を示すものであり、横軸はテスト進行状況である。両矢印で示す範囲が一回の動作テストを示している。縦軸がメモリ使用量である。
図3はタイプ1についての説明図である。タイプ1はメモリ使用量が単調増加傾向を示す現象である。図3Aは障害の場合、図3Bは障害でない場合である。図3Aはテストを繰り返すことにより、メモリ使用量が増大している。テスト対象プログラムが確保したメモリを適切に開放していないことが、メモリ使用量増大の要因であり、障害が発生しているみなすべきである。以降、このような現象を「タイプ1−a」または「1−a」とする。
図3Bでは当初のテスト実行においては、メモリ使用量の増大が続いたが、その後、頭打ちになっている。これは、テスト対象プログラムの仕様として、メモリ使用量の上限を定めている場合である。その上限を超えない範囲においては、必要に応じてメモリを確保するため、当初はメモリ使用量が増大するが、一定のところで頭打ちになるのである。よって、障害ではなく、プログラムの仕様から生じる現象である。以降、このような現象を「タイプ1−b」また「1−b」とする。
図4はタイプ2についての説明図である。テスト実行により、メモリ使用量の増大が生じたが、その後、メモリ使用量は頭打ちとなっている。グラフで表す現象としては1−bと同様であるが、その要因が異なる場合である。例えば、テストを実行時に、テスト対象プログラムとは直接関係しない、イレギュラーな処理がたまたま行われ、その処理において、メモリが開放されなかったために、生じた現象である。イレギュラーな処理の一例としては、ネットワーク異常時に行われるリカバリ処理である。イレギュラーな処理が要因であるため、再テストを行っても再現をせずに、障害でないと判定されてしまう。確かに、テスト対象プログラムが要因ではないため、テスト結果としてはある意味正しいのであるが、イレギュラーな処理であっても障害であるから、検出することが望ましい。
図5はタイプ3についての説明図である。タイプ1と同様にメモリ使用量が単調増加傾向を示す現象であるが、メモリ使用量の増大するタイミンクが、タイプ1と異なる。タイプ3は、上位(プログラム、装置)からのアクセス内容の変化に応じた作業領域の拡張など、所定の条件に合致した場合に使用メモリを拡張する場合である。図5Aのように制限なく拡張し続ける場合は障害である。以降の、このような現象を「タイプ3−a」又は「3−a」とする。図5Bのように、仕様で定めた上限を超えない制御を行っている場合は、障害ではない。以降、このような現象を「タイプ3−b」または「3−b」とする。領域の拡張の例としては、キャッシュ領域が足りなければ増やす、コネクション開設毎にメモリを確保する処理である。タイプ1よりも、メモリ使用量が増大する間隔が広くなるのは、領域を拡張する際にはある程度、まとまったサイズを確保するのが通常であるからである。そのため、再テストを数回行っただけでは、資源の不足が発生せずに領域拡張が起こらないのである。
以上のように、メモリ使用量の増大現象は、タイプ1−a、1−b、2、3−a、3−bの5タイプに類型化される。そのうち、タイプ1−a、2、3−aは障害である。それに対して、タイプ1−b、3−bはプログラムの仕様による現象であり、障害ではない。本実施の形態においては、メモリ使用量の増大現象が5タイプのうちのどのタイプであるかを識別する。そして、障害であるタイプ1−a、2、3−aの場合のみ、再テストを実行する。タイプに則したテストを繰り返すことにより、メモリリークを発生させている可能性の高いプログラムの高精度に特定することが可能となる。
次にタイプを識別するための指針を示す。タイプ1(1−a、1−b)、タイプ3を識別するための指針は以下の通りである。タイプ1は再テストで必ず発生するものであるから、再テストを繰り返し行うことで検出可能である。一方、タイプ3は同じ項目で再テストを繰り返しても、メモリ使用量はすぐには増大しないため、以下の2種類のテストを行う。
(1)最大値テスト
最大値テストは、メモリ使用量の増加を検出したテスト項目で設定した要因に基づき、テストで指定するパラメータを最大値に設定して再テストを行う。このテストを実施した結果、a.仕様で定められたメモリ獲得の上限を超えるメモリ増加があった場合、b.メモリ枯渇によりシステムがハングアップした場合は、障害であると判定できる。
(2)加速テスト
加速テストは、メモリ使用量の増加を検出したテスト項目で設定した要因に基づき、テストで指定するパラメータを最小値から最大値まで変えながらテストを行う。なお、初回のテストで検出した状態は所定のメモリを確保済みの状態であり、確保済みメモリを使いきるまでメモリ使用量は増大しないため、装置を再起動し初期状態に戻した上でテストを行う。加速テストを行うことにより、最大値テストでは障害であるか否か判定できなかった現象の判定を行うことが可能である。
最大値テストの一例をファイルアクセスの場合にて説明する。ファイルアクセスのテストパラメータとして、クライアント数、read長がある。クライアント数が1〜8192の範囲で指定可能である場合、最大値8192としてテストを行うのが、最大値テストである。同様に、read長が1KB〜128MB指定可能な場合に、128MBとしてテストを行うのが、最大値テストである。
加速テストの一例をファイルアクセスの場合にて説明する。パラメータ1は、クライアント数であり、例えば、1,2,4,8,16,32,64,・・・8192のような値を指定する。パラメータ2はread長であり、1KB,2,4,8,16,32KB,・・1MB,2,4,8,16,・・128MBのような値を指定する。加速テストでは、まず、パラメータ2は固定し、パラメータ1を1から順に値を増やしながら、繰り返しテストを行う。次に、パラメータ1を固定して、パラメータ2を1KBから順に増やしながら、繰り返し行う。
加速テストは、1項目あたり数十回〜数百回の再実行が必要であるだけではなく、実施前にシステムの再起動が必要であることから、テスト時間に対するオーバーヘッドが大きい。このため、メモリ使用量の増加を検出した際、タイプ1、タイプ2に該当するか判定した上で、タイプ3の疑いがあるもののみについて、加速テストを行うこととする。最大値テストを実行したした結果から、障害又は仕様通りの動作と判定できたものは、加速テストの対象から除外される。
タイプ2はテスト対象プログラムとは直接関係のない要因による障害であるから、テスト結果のみでは検出できない。そこで、ログデータを用いて判定する。ここで、一般にログを用いたエラー解析では障害が発生した時刻から時間を遡って、一つ一つのログの内容を検討する。しかしながら、全てのプログラムがメモリ使用量増大の要因となりうるので、メモリ使用量の増大を検出した直前のログのみでは、要因を誤ってしまう可能性がある。そのため、検出した時刻からある程度の時間まで遡った時刻までのログを解析するのであれば、解析するログのデータが多くなり、効率が悪い。
そこで、本実施の形態においては、全テストが終了後に、同一プロセスで複数回の同一現象が発生していないか、すなわち、メモリ使用量が増加、かつ同じIDのログが有るか否かを判定する。図6はログデータの一例を示す説明図である。この例では、時刻15:12及び16:15にメモリ使用量の増加を検出したものとする。図6に示すように、プロセス名「filebprovider」、ログID「2498-7766-0011」のログが、それぞれの時刻で記録されていることが分かる。従って、プロセス「filebprovider」がメモリ使用量増大の要因であると判定する。
次に、検出装置1におけるメモリリーク検出処理について説明する。図7は検出処理の手順を示すフローチャートである。検出装置1のCPU10はループカウンタiに1を設定する(ステップS1)。次に、CPU10はプログラムP2−1を実行する(ステップS2)。プログラムP2−1は、対象装置2におけるメモリ使用量を計測するプログラムである。CPU10はi番目のテスト対象プログラム(以下、「テストプログラムi」と記す。)を対象装置2に実行させる(ステップS3)。CPU10はプログラムP2−2を実行する。プログラムP2−2は、主として障害タイプ1−aを検出するプログラムである。CPU10は対象装置2でメモリ使用量が増加したか否かを判定する(ステップS5)。具体的にはプログラムP2−2が戻り値として、「再テスト要」を設定したか否かを判定する。「再テスト要」とはテストプログラムを再度、対象装置2において、動作させる必要が有ることを示す。P2−2が戻り値として「再テスト要」を返しており、メモリ使用量が増加した場合(ステップS5でYES)、CPU10はプログラムP2−1を再度実行する(スフップS6)。CPU10は、テストプログラムiを対象装置2に実行させる(ステップS7)。CPU10はプログラムP2−2を実行する(ステップS8)。CPU10は対象装置2で上限確認が必要か否かを判定する(ステップS9)。上限確認が必要である場合(ステップS9でYES)、CPU10は上限確認処理を行う(ステップS10)。CPU10は処理をステップS11に移す。
対象装置2でメモリ使用量が増加していない場合(ステップS5でNO)又は上限確認が不要の場合(ステップS9でNO)、CPU10は処理をステップS11に移す。CPU10はループカウンタiを1増加する(ステップS11)。CPU10は、ループカウンタiが、SUより大きいか否か判定する(ステップS12)。ここで、SUはテストプログラムの数を示す値である。ループカウンタiがSU以下の場合(ステップS12でNO)、CPU10は処理をステップS2に戻す。
ループカウンタiがSUより大きい場合(ステップS12でYES)、CPU10はプログラムP2−3、P2−4、P2−5を順に実行し(ステップS13、S14、S15)、処理を終了する。プログラムP2−3、P2−4、P2−5共に、メモリリークを検出するプログラムである。
次に、これまでに参照した各プログラムについて、詳細を説明する。図8は、プログラムP2−1が行う処理を示すフローチャ−トである。CPU10は、対象装置2のメモリ使用量を取得する(ステップS21)。ここで、メモリ使用量は、対象装置2で動作する全てのプロセスに対して、プロセス単位で取得するものとする。CPU10はループカウンタiを1に設定する(ステップS22)。CPU10は配列DATA−S(PID)に、対象装置2で動作するi番目のプロセスが使用しているメモリ使用量を格納する(ステップS23)。ここで、PIDは対象装置2で動作するi番目のプロセスのプロセスIDである。CPU10はループカウンタiを1増加させる(ステップS24)。CPU10はループカウンタiが対象装置2で動作するプロセス数より大きいか否か判定する(ステップS25)。ループカウンタiがプロセス数以下である場合(ステップS25でNO)、CPU10は処理をステップS23に戻す。ループカウンタiがプロセス数より大きい場合(ステップS25でYES)、CPU10は処理を終了し、呼び出し元のプログラムに処理を戻す。
図9、図10は、プログラムP2−2が行う処理を示すフローチャートである。プログラムP2−2が実行される際には、引数として、「初回テスト」か「再テスト」であるのか、また、実行されたテスト項目が渡される。CPU10は、対象装置2のメモリ使用量を取得する(ステップS31)。ここで、メモリ使用量は、対象装置2で動作する全てのプロセスに対して、プロセス単位で取得するものとする。CPU10はループカウンタiを1に設定する(ステップS32)。CPU10は変数PIDに、対象装置2で動作するi番目のプロセスのプロセスIDを設定する(ステップS33)。CPU10は配列DATE−E(PID)に、対象装置2で動作するi番目のプロセスが使用しているメモリ使用量を格納する(ステップS34)。CPU10はPIDを配列PLIST−E(i)に格納する(ステップS35)。CPU10はループカウンタiを1増加させる(ステップS36)。CPU10はループカウンタiが対象装置2で動作するプロセス数より大きいか否か判定する(ステップS37)。ループカウンタiがプロセス数以下である場合(ステップS37でNO)、CPU10は処理をS33に戻す。ループカウンタiがプロセス数より大きい場合(ステップS37でYES)、CPU10は再びループカウンタiを1に設定する(ステップS38)。
CPU10は、変数PIDにPLIST−E(i)を設定する(ステップS39)。CPU10は、DATA−S(PID)及びDATA−E(PID)が両方存在するか否かを判定する(ステップS40)。これは、テストプログラム実行前後の両時点で、対象装置2に存在するプロセスのみを、評価対象とするからである。CPU10は、DATA−E(PID)とDATA−S(PID)との差分をDIF(i,PID)に格納する(ステップS41)。CPU10はループカウンタiを1増加させる(ステップS42)。CPU10はループカウンタiが対象装置2で動作するプロセス数より大きいか否か判定する(ステップS43)。ループカウンタiがプロセス数以下である場合(ステップS43でNO)、CPU10は処理をステップS40に戻す。ループカウンタiがプロセス数より大きい場合(ステップS43でYES)、図10に移り、CPU10は再びループカウンタiを1に設定する(ステップS44)。
CPU10は変数PIDにPLIST−E(i)を設定する(ステップS45)。CPU10は、DIF(i,PID)の値が0より大きいか否かを判定する(ステップS46)。DIF(i,PID)の値が0より大きい場合(ステップS46でYES)、CPU10は引数が再テストであるか否かを判定する(ステップS47)。引数が再テストである場合(ステップS47でYES)、CPU10は「上限確認要」であることをRAM11又は大容量記憶装置13に記憶するとともに、プロセス名を配列PROC_LIST()に記憶し(ステップS48)、処理をステップS50に移す。引数が再テストではない、すなわち、初回テストの場合(ステップS47でNO)、CPU10は「再テスト要」であることをRAM11又は大容量記憶装置13に記憶し(ステップS49)、処理を呼び出し元に戻す。
DIF(i,PID)の値が0以下の場合(ステップS46でNO)、CPU10はループカウンタiを1増加させる。(ステップS50)。CPU10はループカウンタiがプロセス数より大きいか判定する(ステップS51)。ループカウンタiがプロセス数以下の場合(ステップS51でNO)、CPU10は処理をステップS45に戻す。ループカウンタiがプロセス数よりも大きい場合(ステップS51でYES)、CPU10は引数が再テストであるか否かを判定する(ステップS52)。引数が再テストではなく、初回テストである場合(ステップS52でNO)、CPU10は戻り値「判定」に正常をセットし(ステップS58)、処理を呼び出し元に戻す。引数が再テストである場合(ステップS52でYES)、CPU10はログ確認を行う(ステップS53)。ログ確認は、ログ管理プログラム(ロギングプログラム)に、PID、ログが記録された時間の範囲を指定して、ログを検索させ、エラーログがないかを調べる。CPU10はログ管理プログラムの処理結果を調べ、エラーログが有った否かを判定する(ステップS54)。エラーログが有った場合(ステップS54でYES)、CPU10は、ログID、プロセス名(またはプロセスID)、及びテスト項目名を紐付けて、増加時ログありデータとして、RAM11又は大容量記憶装置13に記憶し(ステップS55)、処理を呼び出し元に戻す。
エラーログがなかった場合(ステップS54でNO)、CPU10は戻り値「判定」に「障害でない」を設定する(ステップS56)。CPU10は、テスト項目とプロセス名(またはプロセスID)とを紐付けて、再発しないが増加ありデータとして、RAM11又は大容量記憶装置13に記憶し(ステップS57)、処理を呼び出し元に戻す。
図11は上限確認処理の手順を示すフローチャートである。上限確認処理では、引数としてメモリリークの疑いがあるプロセス名が記憶された配列PROC_LIST()が渡される。ここで、配列PROC_LIST()の内容は、図10のステップS48で記憶したものである。また、各プロセスに関する前々回(図7のステップS3)と前回テスト時(図7のステップS7)のメモリ使用量が記憶された配列DATA(1,i)、DATA(2,i)も渡される。まず、CPU10はループカウンタiを3に設定する。ここで、ループカウンタiを3と設定するのは、図7で示したように、テストプログラム2回動作させて、いずれもメモリ使用量の増加を示した場合に、上限確認処理が呼ばれるからである。すなわち、上限確認処理にて、再度、テストプログラムを動作させるのが、通算3回目となるからである。CPU10はテストプログラムの再実行を指示する(ステップS62)。CPU10はテストプログラムの実行が正常に完了したか否かを判定する(ステップS63)。テストプログラムが正常に完了しなかった場合(ステップS63でNO)、CPU10は戻り値「判定」に「障害」をセットし、戻り値「タイプ」に「1−a」を設定し(ステップS64)、呼び出し元に処理を戻す。ここで、テストプログラムが正常に完了しないのは、メモリリークが繰り返されたために、対象装置2がハングアップすることが想定される。
テストプログラムの実行が正常に完了した場合(ステップS63でYES)、CPU10はループカウンタjを1に設定する(ステップS65)。CPU10は対象装置2で動作しているj番目のプロセスのメモリ使用量を取得する(ステップS66)。CPU10は、DATA(i, j)とDATA(j-1,j)との差分が、0より大きいか判定する(ステップS67)。DATA(i, j)とDATA(j-1,j)との差分が0より大きい場合(ステップS67でYES)、CPU10はループカウンタjを1増加させる(ステップS68)。CPU10はループカウンタjがプロセス数をより大きいか判定する(ステップS69)。プロセス数以下であれば(ステップS69でNO)、CPU10は処理をステップS66に戻す。
DATA(i, j)とDATA(j-1,j)との差分が0以下の場合(ステップS67でNO)、メモリ使用量の増加が止まったので、仕様とみなす。すなわち、CPU10は戻り値「判定」に「仕様」をセットする。戻り値「タイプ」に「1−b」をセットする(ステップS73)。CPU10はプロセス名とテスト項目名を紐付けて上限プロセスリスト(タイプ1)に記憶する(ステップS74)。CPU10は処理を呼び出し元に戻す。上限プロセスリスト(タイプ1)は、RAM11、大容量記憶装置13等に記憶する。
CPU10はループカウンタjがプロセス数より大きいのであれば(ステップS69でYES)、CPU10はループカウンタiの値を1増加させる(ステップS70)。CPU10はループカウンタiの値が繰り返し回数Nより大きいか否か判定する(ステップS71)。ここで、繰り返し回数Nは、3以上の値を予め設定しておくものとする。ループカウンタiの値が繰り返し回数N以下の場合(ステップS71でNO)、CPU10は処理をステップS62に戻す。ループカウンタiの値が繰り返し回数Nより大きい場合(ステップS71でYES)、CPU10は戻り値「判定」に「障害」を設定し、戻り値「タイプ」に1−aを設定し(ステップS72)、処理を呼び出し元に戻す。
以上のように、上限確認処理により、メモリ使用量の増加が頭打ちになるであれば仕様(タイプ1−b)であると判定し、メモリ使用量が増加を続ければ、メモリリーク(タイプ1−a)と判定する。なお、ステップS66からステップS69のプロセスごとにメモリ使用量が増加しているか否かの判定は、配列PROC_LIST()に記憶されているメモリリークの疑いがあるプロセスのみに行うこととしても良いし、全てのプロセスとしても良い。
次に、プログラムP2−3の処理について、説明する。プログラムP2−3では、プログラムP2−2で「増加時ログあり」と判定されたプロセス及び「再発しないが増加」と判定されたプロセスについて、さらに検証を行う。図12及び図13はプログラムP2−3が行う処理を示すフローチャートである。
CPU10は、RAM11又は大容量記憶装置13に記憶してある増加時ログありデータ(リスト)を取得する(ステップS81)。増加時ログありデータ(リスト)は、ログID、プロセス名及びテスト項目を紐付けたリストである。以降このリストをLIST1という。CPU10は取得したLIST1からプロセス名を配列PROC()にセットする(ステップS82)。CPU10はログ管理プログラムに問い合せを行い、配列PROC()に設定されているプロセスのログデータを取得する(ステップS83)。ログデータの検索範囲は、最初のテスト開始時刻から最後のテストの終了時刻までの範囲である。ここで、取得したログデータのリストを以降LIST2という。
CPU10はループカウンタiを1に設定する(ステップS84)。次に、CPU10は、LIST1でi番目のプロセスと紐付けられたログIDの件数を、ログID毎にカウントする(ステップS85)。CPU10はカウントが2件以上であるログIDがあるか否かを判定する(ステップS86)。ログIDが1件の場合(ステップS86でNO)、LIST2より、i番目のプロセスに対応するログを配列log(i, j)にセットする(ステップS87)。CPU10は配列log(i, j)にセットしたログデータに対して、ステップS86で1件とカウントされたログIDを検索する(ステップS88)。CPU10はログIDが見つかった否かを判定する(ステップS89)。ログIDが見つかった場合(ステップS89でYES)、CPU10はテスト項目と「障害でない」旨の情報とを対応付けて記憶する(ステップS90)。ログIDが見つからなかった場合(ステップS89でNO)、CPU10はテスト項目と「判定不可(情報不足)」の情報とを対応付けて記憶する(ステップS91)。
カウントが2件以上の場合(ステップS86でYES)、CPU10はテスト項目に「障害(タイプ2)」をセットする(ステップS92)。CPU10はループカウンタiを1増加させる(ステップS93)。CPU10はループカウンタiがプロセス数Sより大きいかを判定する(ステップS94)。ループカウンタiがプロセス数以下の場合(ステップS94でNO)、CPU10は処理をステップS85に戻す。ループカウンタiがプロセス数以下の場合(ステップS94でYES)、CPU10は処理をステップS95に進める。
次に、CPU10は、再発しないが増加ありデータを取得する(ステップS95)。CPU10は取得した件数が0より大きいか判定する(ステップS96)。件数が0件である場合(ステップS96でNO)、CPU10は処理を終了し、呼び出し元に処理を戻す。件数が0より大きい場合(ステップS96でYES)、CPU10はプロセス名でソートを行う(ステップS97)。CPU10はプロセス名の数をカウントし、その値をNUMにセットする(ステップS98)。CPU10はループカウンタiを1にセットする(ステップS99)。CPU10はi番目のプロセスに関するデータが複数あるか否か判定する(ステップS100)。データが複数件ではない場合(ステップS100でNO)、CPU10は処理を終了し、呼び出し元に処理を戻す。
データが複数件の場合(ステップS100でYES)、CPU10はRAM11にテスト項目とプロセス名を追加して記憶する(ステップS101)。CPU10はループカウンタiを1増加させる(ステップS102)。CPU10はループカウンタiがプロセス名の数NUMより大きいか判定する(ステップS103)。ループカウンタiがNUMより大きくない場合(ステップS103でNO)、CPU10は処理をステップS100に戻す。ループカウンタiがNUMより大きい場合(ステップS103でYES)、CPU10はテスト項目、プロセス名を上限プロセスリスト(タイプ3)に記憶する(ステップS104)。CPU10は復帰値(戻り値)に「加速テスト要」をセットし(ステップS105)、処理を呼び出し元に戻す。なお、上限プロセスリスト(タイプ3)は、RAM11、大容量記憶装置13等に記憶する。
次に、プログラムP2−4について説明する。プログラムP2−4は上述した最大値テストを実行させるプログラムである。図14及び図15はプログラムP2−4が行う処理を示すフローチャートである。CPU10はテスト数を変数KAZUに設定する(ステップS111)。テスト数は、上述の上限プロセスリスト(タイプ3)に記憶されている。CPU10はテスト毎に変化させるパラメータの種類を配列T_KIND()にセットする(ステップS112)。CPU10はループカウンタiを1に設定する(ステップS113)。続いて、CPU10はループカウンタKINDにも1を設定する(ステップS114)。CPU10は最大値テストを実行させる(ステップS115)。最大値テストにおける個々のテストでは、開始時と終了時にメモリ使用量が計測され、それぞれ、配列DATA_S()、DATA_E()に格納されているものとする。例えば、i番目のテストにおいて、j番目のパラメータが最大値を指定して実行した場合において、l(エル)番目のプロセスのテスト開始時及び終了時の使用メモリ量は、それぞれ、DATA_S(i, j, l)、DATA_E(i,j,l)に格納されている。
CPU10は最大値テストにおけるメモリの使用量差分を求め、所定の配列にセットする(ステップS116)。図16は使用量差分セットの手順を示すフローチャートである。なお、図面においては、l(エル)をリットル記号で表記している。CPU10はループカウンタi、ループカウンタj、ループカウンタlの値をそれぞれ1に設定する(ステップS131、S132、S133)。CPU10はテスト終了時のメモリ使用量DATA_E(i, j, l)及びテスト開始時のメモリ使用量DATA_S(i, j, l)の差分を求め、DIFF(i, j, l)に格納する(ステップS134)。CPU10はループカウンタlを1増加させる(ステップS135)。CPU10はループカウンタlがプロセス数より大きいか判定する(ステップS136)。ループカウンタlがプロセス数以下である場合(ステップS136でNO)、CPU10は処理をステップS134に戻す。ループカウンタlがプロセス数より大きい場合(ステップS136でYES)、CPU10は、ループカウンタjを1増加させる(ステップS137)。CPU10はループカウンタjがT_KIND(i)より大きいか判定する(ステップS138)。T_KIND(i)は、前述したように変化させるパラメータ種類数を表す。ループカウンタjがT_KIND(i)より大きくない場合(ステップS138でNO)、CPU10は処理をステップS133に戻す。ループカウンタjがT_KIND(i)より大きい場合(ステップS138でYES)、CPU10はループカウンタiを1増加させる(ステップS139)。CPU10はループカウンタiがテスト数KAZUより大きいか否かを判定する(ステップS140)。ループカウンタiがテスト数KAZUより大きくない場合(ステップS140でNO)、CPU10は処理をステップS132に戻す。ループカウンタiがテスト数KAZUより大きい場合、CPU10は処理を終了し、呼び出し元に処理を戻す。
図14に戻り、CPU10は最大値テストが正常に完了したか否かを判定する(ステップS117)。最大値テストが正常に完了しなかった場合(ステップS117でNO)、CPU10は戻り値「判定」に「障害」をセットし、戻り値「タイプ」に「3−a」をセットして(ステップS130)、処理を終了する。
最大値テストが正常に完了した場合(ステップS117でYES)、CPU110はループカウンタi、j、lを1に設定する(ステップS118、S119、S120)。CPU10はメモリ使用量の上限値が既知であるか判定する(ステップS121)。マニュアル、仕様書等でメモリ獲得量の上限値が明確になっている場合、予め大容量記憶装置13等に記憶しておく。メモリ使用量の上限値が既知である場合(ステップS121でYES)、CPU10はDIFF(i,j,l)が、既知の上限値より大きいか否かを判定する(ステップS122)。既知の上限値より大きい場合(ステップS122でYES)、CPU10は戻り値「判定」に「障害」をセットし、戻り「タイプ」に「3−a」をセットし(ステップS130)、処理を終了し、呼び出し元に処理を戻す。
DIFF(i,j,l)が既知の上限値より小さい場合(ステップS122でNO)、CPU10はループカウンタlを1増加させる(ステップS123)。CPU10はループカウンタlがプロセス数より大きいか否か判定する(ステップS124)。ループカウンタlがプロセス数以下の場合(ステップS124でNO)、CPU10は処理をステップS121へ戻す。ループカウンタlがプロセス数より大きい場合(ステップS124でYES)、CPU10はループカウンタjを1増加させる(ステップS125)。CPU10はループカウンタjがT_KIND(i)より大きいか否かを判定する(ステップS126)。ループカウンタjがT_KIND(i)以下の場合(ステップS126でNO)、CPU10は処理をステップS120へ戻す。ループカウンタjがT_KIND(i)より大きい場合(ステップS126でYES)、CPU10はテスト項目とプロセス名を対応付けてRAM11や大容量記憶装置13に記憶する(ステップS127)。CPU10はループカウンタiを1増加させる(ステップS128)。CPU10はループカウンタiがKAZUより大きいか否かを判定する(ステップS129)。ループカウンタiがKAZU以下の場合(ステップS129でNO)、CPU10は処理をステップS119に戻す。ループカウンタiがKAZU以下の場合(ステップS129でYES)、CPU10は処理を終了し、呼び出し元に処理を戻す。
メモリ確保量の上限値が既知ではない場合(ステップS121でNO)、CPU10はステップS127以降を実行する。具体的な内容は上述の通りである。
次に、プログラムP2−5が行う処理内容について説明する。プログラムP2−5は上述した加速テストを実行させるプログラムである。プログラムP2−5は、プログラムP2−4までの処理を経てもメモリリークであるか否か判定できなかったものについて、検証を行う。すなわち、図15のステップS127で記憶したプロセスについて行う。検証すべきプロセスについては、例えば、プロセス名が格納された配列PROC_LIST()が引数としてプログラムP2−5に渡される。
図17及び図18はプログラムP2−5が行う処理を示すフローチャートである。
CPU10は対象となるテスト数を変数KAZUに設定する(ステップS151)。上述したステップS127で記憶したテスト項目の数に対応する。CPU10はテスト毎に変化させるパラメータの種類数を配列T_KIND(i)に記憶する(ステップS152)。CPU10はパラメータ毎のテスト数を配列T_ITEM(l,i)に格納する(ステップS153)。CPU10はループカウンタiを1にセットする(ステップS154)。CPU10は加速テストを実行させる(ステップS155)。加速テストで行う各テストの前後では、プロセス毎にメモリ使用量が取得される。i番目のテストにおいて、j番目のパラメータにおけるk番目の指定値で実施した際のl番目のプロセスの使用メモリ量は、開始時の値がDATA_S(i,j,k,l)に、終了時の値がDATA_E(i,j,k,l)に格納される。
CPU10はメモリ使用量の差分を求める処理(使用量差分セット2)を行う(ステップS156)。図19は使用量差分セット2で行う処理についてのフローチャートである。CPU10はループカウンタi、j、k、lに1を設定する(ステップS181、S182、S183、S184)。CPU10はメモリ使用量の差分、すなわち、DATA_E(i,j,k,l)とDATA_S(i,j,k,l)との差分値をDIFF(i,j,k,l)に格納する(ステップS185)。CPU10はループカウンタlを1増加させる(ステップS186)。CPU10はlがプロセス数より大きいか否かを判定する(ステップS187)。ループカウンタlがプロセス数以下の場合(ステップS187でNO)、CPU10は処理をステップS185に戻す。ループカウンタlがプロセス数より大きい場合(ステップS187でYES)、CPU10はループカウンタkを1増加させる(ステップS188)。CPU10はループカウンタkがT_ITEM(l,i)より大きいか否かを判定する(ステップS189)。ループカウンタkがT_ITEM(l,i)以下である場合(ステップS189でNO)、CPU10は処理をステップS184に戻す。ループカウンタkがT_ITEM(l,i)より大きい場合(ステップS189でYES)、CPU10はループカウンタjを1増加させる(ステップS190)。CPU10はループカウンタjがT_KIND(i)より大きいか否かを判定する(ステップS191)。ループカウンタjがT_KIND(i)以下の場合(ステップS191でNO)、CPU10は処理をステップS183に戻す。ループカウンタjがT_KIND(i)より大きい場合(ステップS191でYES)、CPU10はループカウンタiを1増加させる(ステップS192)。CPU10はループカウンタiがKAZUより大きいか否かを判定する(ステップS193)。ループカウンタiがKAZU以下の場合(ステップS193でNO)、CPU10は処理をステップS182に戻す。ループカウンタiがKAZUより大きい場合(ステップS193でYES)、CPU10は処理を終了し、呼び出し元に処理を戻す。
図17に戻り、CPU10は加速テストが正常に完了したか否かを判定する(ステップS157)。正常に完了しなかった場合は、加速テスト実行によりメモリリークが繰り返し発生し、対象装置2のメモリが枯渇したのが、その原因と考えられるからである。したがって、加速テストが正常に完了しなかった場合(ステップS157でNO)、CPU10は戻り値「判定」に「障害」を、戻り値「タイプ」に「3−a」をセットする(ステップS174)。CPU10は処理を終了し、呼び出し元に処理を戻す。
加速テストが正常に完了した場合(ステップS157でYES)、CPU10はループカウンタi、j、kに1を設定する(ステップS158、S159、S160)。CPU10はメモリ使用量の上限値が既知であるか否かを判定する(ステップS161)。これは、上述した図14のステップS121と同様の処理であるので、詳細は省略する。上限値が既知の場合(ステップS161でYES)、CPU10はループカウンタlに1を設定する(ステップS170)。CPU10はメモリ使用量DATA_E(i, j, k, l)とDATA_S(i,k,1,l)との差分が上限値以上であるか否かを判定する(ステップS171)。差分が上限値以上である場合(ステップS171でYES)、CPU10は戻り値「判定」に「障害」を、戻り値「タイプ」に「3−a」をセットする(ステップS174)。
差分が上限値に達していない場合(ステップS171でNO)、CPU10はループカウンタlを1増加させる(ステップS172)。CPU10はループカウンタlがプロセス数より大きいか否かを判定する(ステップS173)。ループカウンタlがプロセス数以下の場合(ステップS173でNO)、CPU10は処理をステップS171に戻す。ループカウンタlがプロセス数より大きい場合(ステップS173でYES)、CPU10は処理をステップS162に移す。上述のステップS161で上限値が既知でない場合(ステップS161でNO)も、CPU10は処理をステップS162に移す。
図18に移り、CPU10は差分値DIFF(i,j,k,l)の値の列において、後半の10%で正の値があるか否かを判定する(ステップS162)。後半の10%でも増加するものがある場合は、上限なく使用メモリを拡張したことを意味している。後半の10%に正の値がある場合(ステップS162でYES)、CPU10は戻り値「判定」に「判定不可」を設定する(ステップS175)。CPU10は処理を終了し、呼び出し元に処理を戻す。
後半の10%に正の値がない場合(ステップS162でNO)、CPU10はループカウンタkを1増加させる(ステップS163)。CPU10はループカウンタkがT_KIND(j,i)より大きいか否かを判定する(ステップS164)。ループカウンタkがT_KIND(j,i)以下の場合(ステップS164でNO)、CPU10は処理をステップS161へ戻す。ループカウンタkがT_KIND(j,i)より大きい場合(ステップS164でYES)、CPU10はループカウンタjを1増加させる(ステップS165)。CPU10はループカウンタjがT_KIND(i)より大きい否かを判定する(ステップS166)。ループカウンタjがT_KIND(i)以下の場合(ステップS166でNO)、CPU10は処理をステップS160に戻す。ループカウンタjがT_KIND(i)より大きい場合(ステップS166でYES)、CPU10はループカウンタiを1増加させる(ステップS167)。CPU10はループカウンタiがKAZUより大きいか否か判定する(ステップS168)。ループカウンタiがKAZU以下の場合(ステップS168でNO)、CPU10は処理をS159に戻す。ループカウンタiがKAZUより大きい場合(ステップS168でYES)、CPU10は戻り値「判定」に「仕様」を、戻り値「タイプ」に「3−b」をセットする(ステップS169)。CPU10は処理を終了し、呼び出し元に処理を戻す。
なお、後半10%とは、i番目のテストにおいて、j番目のパラメータの値を変化させていった場合の値の列の後半10%ということである。
上述のメモリリーク検出処理は、テスト前後のメモリ使用量比較するものであった。テストにはそのようなものだけではなく、一定時間放置しておき、メモリの使用量を比較するというテスト項目もある。これは、定期的に実行される処理(デバイス、負荷状態等に関する監視処理、情報の配布処理等)に対するリーク障害の有無を検証するためである。
当該検証法方法について、以下に説明する。
図20は一定時間放置におけるメモリリーク検出処理についてのフローチャートである。この検出処理が呼ばれる場合には、引数として初期時刻、最終時刻、測定間隔が指定される。CPU10は、初期時刻、測定間隔を元に、最初の測定時刻、測定の間隔をRAM11等の作業領域に設定する(ステップS201)。CPU10は、初期時刻、最終時刻、測定回数から測定数を算出する(ステップS202)。CPU10は、算出した測定数を変数NUMに格納する(ステップS203)。CPU10はループカウンタiに1を設定する(ステップS204)。CPU10は測定1を行う(ステップS205)。
図21は測定1の処理内容を示すフローチャートである。CPU10はループカウンタkに1を設定する(ステップS221)。CPU10は使用メモリ量の測定を行う(ステップS222)。CPU10はループカウンタkを1増加させる(ステップS223)。CPU10はループカウンタkが基礎測定数より大きいか否かを判定する(ステップS224)。ここで、一回のデータ取得を一回の測定としてしまうと、計測誤差があった場合、測定値にバラツキが発生する。そこで、一回の測定では複数回のデータ取得を行い、その平均値を測定値する。データ取得の回数を基礎測定数という。例えば、基礎測定回数は3回である。ループカウンタkが基礎測定数より小さい場合(ステップS224でNO)、CPU10は次の測定まで待機する(ステップS225)。待機後、CPU10はステップS222に処理を移す。ここで、待機する時間の一例は5から10秒である。
ループカウンタkが基礎測定数より大きい場合(ステップS224でYES)、CPU10は、ループカウンタjに1を設定する(ステップS226)。CPU10はj番目のプロセスについての取得結果から、異常値の除去を行う(ステップS227)。例えば、基礎測定回数が3回の場合は、3つの測定値の平均値を求め、最も平均値から離れている値を除去する。CPU10は残りの値の平均値を算出する(ステップS228)。CPU10は算出した値を、DATA(i,j)に、対象となったプロセスのプロセス名をPROC(j)に格納する(ステップS229)。CPU10はループカウンタjを1増加させる(ステップS230)。CPU10はループカウンタjがプロセス数より大きいか否か判定する(ステップS231)。ループカウンタjがプロセス数以下の場合(ステップS231でNO)、CPU10は処理をステップS227へ戻す。ループカウンタjがプロセス数より大きい場合(ステップS231でYES)、CPU10は処理を終了し、呼び出し元に処理を戻す。
図20に戻り、CPU10はループカウンタiを1増加させる(ステップS206)。CPU10はループカウンタiが測定数NUMより大きいか否か判定する(ステップS207)。ループカウンタiがNUM以下の場合(ステップS207でNO)、CPU10は処理をステップS205に戻す。ループカウンタiがNUMより大きい場合(ステップS207でYES)、CPU10は判定処理1を行う(ステップS208)。
図22は判定処理1の処理内容を示すフローチャートである。CPU10はループカウンタjを1に設定する(ステップS241)。CPU10はループカウンタiを1に設定する(ステップS242)。CPU10は連続する測定結果の比較し値が増加していないか、すなわち、DATA(i+1,j)の値がDATA(i,j)より大きいか否か判定する(ステップS243)。DATA(i+1,j)の値がDATA(i,j)より大きい場合(ステップS243でYES)、CPU10は障害フラグをONにする(ステップS248)。CPU10は対象となったプロセスのプロセス名(PROC(j))を配列INC_PROC()に追加する(ステップS249)。CPU10は処理をステップS246に移す。
連続する測定結果に増加が見られない場合(ステップS243でNO)、CPU10はループカウンタiを1増加させる(ステップS244)。CPU10はループカウンタiがNUMより大きいか否か判定を判定する(ステップS245)。ループカウンタiがNUM以下の場合(ステップS245でNO)、CPU10は処理をステップS243に戻す。ループカウンタiがNUMより大きい場合(ステップS245でYES)、CPU10はループカウンタjを1増加させる(ステップS246)。CPU10はループカウンタjがSU(プロセス数)より大きいか否か判定する(ステップS247)。ループカウンタjがSU以下の場合(ステップS247でNO)、CPU10は処理をステップS242に戻す。ループカウンタjがSUより大きい場合(ステップS247でYES)、CPU10は処理を終了し、呼び出し元に処理を戻す。
図20に戻り、CPU10は障害フラグがONか否かを判定する(ステップS209)。障害フラグがONの場合(ステップS209でYES)、CPU10はRAM11等の作業領域にあるINC_PROCを不揮発性の大容量記憶装置13に格納する(ステップS210)。CPU10は戻り値「完了コード」に1−aをセットする(ステップS211)。CPU10は処理を終了する。
障害フラグがONでない場合(ステップS209でNO)、CPU10は戻り値「完了コード」に障害なしをセットする(ステップS212)。
次に、処理結果を表示する処理について説明する。図23は検証結果表示処理を示すフローチャートである。CPU10は、RAM11、大容量記憶装置13等に記憶した上限プロセスリスト(タイプ1)、上限プロセスリスト(タイプ3)を読み込む(ステップS251)。CPU10は、読み込んだ2つのリストを元に、プロセス名、判定結果のタイプ等を表示する(ステップS252)。
なお、ここでは省略したが、図20から図22での処理結果についても、大容量記憶装置13に記憶した配列INC_PROC()を用いて、結果を表示することが可能である。
次に、データサンプルを用いて、障害の判定例を説明する。図24はタイプ1−aの判定例を示すための説明図である。測定結果d1は初回テスト実施前、すなわち、図7のステップS2においてプログラムP2−1が動作し、取得したプロセス毎のメモリ使用量である。次に、テストプログラムが実行される(図7のステップS3)。その直後に、プログラムP2−2が実行される。ここでプログラムP2−2に渡される引数は「初回テスト」である。プログラムP2−2では、図9のステップS31からS37の処理により、各プロセスのメモリ使用量が再度、取得される。それを表したのが、図24の測定結果d2となる。
プログラムP2−2では、図9のステップS38からS46にかけて、テストプログラムの実行前後で各プロセスのメモリ使用量の増加がないか否かが検証される。図24に示した測定結果d2とd1との間では、プロセス名ps2、ps3のプロセス(以下、それぞれを「プロセスps2」、「プロセスps3」と記す。)のメモリ使用量が増加している。この2つのプロセスについては、図10のステップS46でYESと判定され、引数は初回テストであるから、ステップS49に流れ、再テスト対象となる。
再テスト対象となるから、図7のステップS5でYESと判定され、ステップS6でプログラムP2−1が実行される。その結果が、図24の例では測定結果d3となる。次に、図7のフローチャートにおいて、ステップS7が実行され、テストプログラムが再度、実行される。そして、プログラムP2−2が実行される。この場合の引数は「再テスト」である。プログラムP2−2で取得されるメモリ使用量は、図24の測定結果d4である。ここで、d4とd3とを比べると、プロセスps2はメモリ使用量が増加しているが、プロセスps3はメモリ使用量が増加してない。
したがって、プロセスps2については、図10のステップS46で再びYESとなり、引数は再テストであるから、ステップS47でYESとなり、上限確認が必要なプロセスとなる。一方、プロセスps3については、ステップS46でNOとなり、タイプ1からの候補からは外れることとなる。
プログラムP2−2の実行後、プロセスps3は上限確認が必要なプロセスとされているから、図7のステップS9はYESと判定され、上限確認処理が実行される(ステップS10)。図11に示したように、上限確認処理では繰り返し、テストプログラムが実行され、所定回数実行しても、ターゲットとなるプロセスの使用メモリ量が増加し続ける場合、タイプ1−aのメモリリークが発生したと判断する。図24に示した例では、測定結果d6、d7、d8と増加を続けたことから、タイプ1−aの障害が発生している判定する。
次に、タイプ1−bの判定例を示す。図25は、タイプ1−bの判定例を示すための説明図である。上限確認処理までは、タイプ1−aと同様であり、図25に示した結果も同様であるので、説明を省略する。
図25に示した例では、通算30回目のテストプログラム実施後に、プロセスps2のメモリ使用量の増加が止まっている(測定結果d9、d10が同じとなっている)。この場合、図11のフローチャートにおいては、ステップS67でNOと判断されることとなるから、判定=仕様、タイプ1−bとの結果となる。
次に、タイプ2の判定例を示す。図26は、タイプ2と判定される測定結果の一例を示す説明図である。図27、図28は、タイプ2の判定に用いられるログデータの一例を示す説明図である。再テストが実行されるまでは、上述したタイプ1と同様であるので、簡単に説明する。図26に示す例では、初回テストでプロセスps3のメモリ使用量が増加したが、再テストではメモリ使用量の増加が見られていない。この場合、図10に示したフローチャートで、ステップS46がYES、ステップS52でYESと判定され、ログの確認がされる(ステップS53)。
上述したようにステップS53では、ログ管理プログラムに対して、プロセス名と時刻を指定して検索を指示する。この例では、プロセスps3について、実行時刻を指定して、検索を指示する。図27に示したログL1ではレコードL11が問題となっているプロセスps3についてのレコードである。レコードL11ではログIDが2498−7766−0011である。したがって、図10のステップS54でYESと判定され、ステップS55で増加時ログありデータとして出力される。
図28に示しているログデータは、増加時ログありデータであり、すべてのテストが終了された後のデータである。すなわち、図7でのフローチャートで言えば、ステップS12でYESと判定された後の状態である。タイプ2の最終的な判定は、図7ではステップS13で実行されるプログラムP2−3で行われる。図12に示すフローチャートのステップS81で読み込まれるのが、「増加時ログあり」リストの一例が図28で示すものである。ここで、注目しているプロセスはプロセスps3であり、ログIDが上述の2498−7766−0011である。図12のステップS85において、同じログIDを持つレコードのカウントがされるが、図28に示した例では、プロセス名ps3で、ログIDが2498−7766−0011を持つレコードはL21、L22の2件である。したがって本例では、図12のステップS86でYESと判定され、ステップS92でタイプ2と認定されることとなる。
次に、タイプ3−aの判定例を示す。初回テスト、再テストの結果については、タイプ2と同様である。異なるのは、テスト実行期間に対象プロセスのログが存在しない点が、タイプ2と異なる。ここでは、プロセスps3がメモリリークの疑われているプロセスであるとして、以降、説明を行う。
図29、図30はタイプ3の判定に用いられるログデータの一例を示す説明図である。タイプ3の場合、初回テストではメモリ使用量が増加したが、再テストではメモリ使用量が増加しない。そのため、図10のフローチャートでステップS53まで辿り着くことは、上述したタイプ2と同様である。図29はステップS53で検索されるログの一例である。ここで、着目しているプロセスはps3であるが、ログL3にはps3についてのレコードは存在しない。したがって、図10のフローチャートのS54ではNOとの判定がされ、この時点では障害でないものと判定される(ステップS56)。しかしながら、より詳しい検証が必要となるため、再発しないが増加ありデータとしてテスト項目とプロセス名が記憶される(ステップS57)。再発しないが増加ありデータについての検証は、プログラムP2−3で行われる。図13の示すフローチャートのステップS95で以降である。
図13のステップS95で読み込まれるデータの一例が、図30に示したデータL4である。図13のステップS100で同一プロセスについて記録が複数あるかが検証される。図30に示す例では、着目しているプロセスps3のレコードは2件(L41、L42)存在している。したがって、ステップS100でYESと判定され、加速テストが必要と判断される。
図31は最大値テストの実行結果の一例を示す説明図である。ここで、着目しているプロセスps3のメモリ獲得量の上限値は300であることが既知であるとする。図17で示すフローチャートでは、ステップS161でYES判定される。ステップS171でメモリ使用量の増大が評価される。図31に示す例では、1番目のパラメータの最大値テストでは、メモリ使用量は変化せず問題は発生していない。2番目のパラメータの最大値テストでは、メモリ使用量は増大しているものの、既知である獲得量の上限値に等しい値であるから、これも問題はないと判定される。しながら、n番目のパラメータの最大値テストでは、メモリ使用量が増大し、しかも、上限値の300を超えているため、障害が発生している判定される。すなわち、図17のステップS171でYESと判定され、タイプ3−aの障害と判定される(ステップS174)。
次に、タイプ3−bと判定される例を示す。加速テストが実行されるまでは、タイプ3−aと同様である。ここで、着目しているプロセスps3のメモリ獲得量の上限は既知ではないとする。図17に示すフローチャートおいて、ステップS161はNOと判定されることとなる。図32は、加速テストの実行結果の一例を示す説明図である。図32のようにいずれのパラメータのテストにおいても後半の10%のテストでメモリ使用量の増加ないため、障害は発生していないと判定され、タイプ3−bとされる。
以上のように、本実施の形態においては、メモリリークを類型化し、その類型の当てはまることを確かめるためのテスト戦略を組んでいる。そのことにより、効率的にメモリリークを検出することが可能となる。特に工数を必要とする加速テストについては、タイプ3に当てはまる可能性がある場合にのみ実行するので、効率的にテストを行うことが可能となる。
図33は検出装置1の機能ブロックの一例を示すブロック図である。CPU10が制御プログラム1Pを実行することにより、検出装置1は以下のように動作する。計測部10aは、メモリ使用量を計測する。設定部10bは試験対象となるプログラムの入力パラメータを設定する。実行部10cは試験対象となるプログラムを実行させる。判定部10dは、試験対象となるプログラムの実行後に計測したメモリ使用量が、実行前のメモリ使用量より所定値以上増加しているとき、プログラム実行によりメモリリークの可能性ありと判定する。検索部10eは試験対象となるプログラム関するエラーログを検索する。記憶部10fはメモリ使用量、メモリリークの可能性のあるプロセス名(プロセスID)などを記憶する。計数部10gはエラーログの出現回数をカウントする。
上述の実施の形態では、メモリ資源に関するリーク障害について説明したが、その他の資源(OSから獲得するファイルディスクリプタ、ハンドルなどの資源)に対しても、同じ方法により障害や仕様であるかどうかを判定可能である。
各実施例で記載されている技術的特徴(構成要件)はお互いに組合せ可能であり、組み合わせすることにより、新しい技術的特徴を形成することができる。
今回開示された実施の形態はすべての点で例示であって、制限的なものでは無いと考えられるべきである。本発明の範囲は、上記した意味では無く、特許請求の範囲によって示され、特許請求の範囲と均等の意味及び範囲内でのすべての変更が含まれることが意図される。
以上の実施形態に関し、さらに以下の付記を開示する。
(付記1)
コンピュータに、
試験対象となるプログラム実行前にメモリ使用量を計測し、
前記プログラムの入力パラメータを設定して前記プログラムを実行し、
前記プログラムの実行後に、メモリ使用量を計測し、
計測したメモリ使用量が前記プログラム実行前のメモリ使用量より所定値以上増加している場合、前記プログラムを再実行し、
前記プログラム再実行後に、メモリ使用量を計測し、
前記プログラム再実行後に計測したメモリ使用量が、前記プログラム再実行前のメモリ使用量より所定値以上増加しているとき、前記プログラム実行によりメモリリークの可能性ありと判定する
処理を実行させるコンピュータプログラム。
(付記2)
メモリリークの可能性ありと判定した場合、前記プログラムを反復実行し、
前記プログラムの実行の前後でメモリ使用量を計測し、
前記プログラムの実行の前後でメモリ使用量が増加して続けるときは、メモリリークであると判定し、
前記プログラムの実行の前後でメモリ使用量の増加が止まったときは、メモリリークではないと判定する
処理を実行させる付記1に記載のコンピュータプログラム。
(付記3)
前記プログラムの実行は試験項目と対応付けがされており、
前記プログラムの実行の前後で行うメモリ使用量の計測は、前記プログラムを実行するコンピュータで実行されている複数のプロセスそれぞれについて行うものであり、
プロセスそれぞれについて、
前記プログラム実行の前後でメモリ使用量を測定し、
前記プログラム実行の前後で、メモリ使用量が略同一の場合、前記プログラム実行中における前記プログラム関するエラーログを検索し、
検索にヒットしたときは、ヒットしたエラーログのIDと、プロセスのIDと、前記プログラムの実行に対応する試験項目のIDとを対応付けて第1プロセスリストに記憶し、
検索にヒットしなかったときは、前記プログラムの実行に対応する試験項目のIDと、プロセスのIDとを対応付けて第2プロセスリストに記憶する
処理を実行させる付記1又は付記2に記載のコンピュータプログラム。
(付記4)
前記試験項目と前記試験対象となるプログラムとの組み合わせが、予め複数定められており、全ての組み合わせに従い、複数の試験対象となるプログラムが実行され、その実行の前後でメモリ使用量の計測が行われるようにしてあり、
全ての試験項目についてのプログラムの実行後に、
前記第1プロセスリストに含まれるプロセスのIDとエラーログのIDとの組み合わせ毎に件数をカウントし、
カウントした件数が2件以上の組み合わせについては、それら組み合わせと対応する試験項目のIDと、障害のタイプ2を示す情報とを一時リストに出力し、
カウントした件数が1件のみの組み合わせについては、最初の試験対象となるプログラムが実行された日時から、最後の試験対象となるプログラムが終了した日時までのエラーログを取得し、
前記組み合わせに含まれるプロセスのIDと対応するエラーログのIDを読み込み、
読み込んだエラーログのIDが前記エラーログに含まれるか否かを判定し、
前記エラーログのIDが含まれている場合、前記組み合わせと対応する試験項目のIDと、障害でないことを示す情報とを一時リストに出力し、
前記エラーログのIDが含まれていない場合、前記組み合わせと対応する試験項目のIDと、判定不可とであることを示す情報とを一時リストに出力する
処理を実行させる付記3に記載のコンピュータプログラム。
(付記5)
前記試験項目と前記試験対象となるプログラムとの組み合わせが、予め複数定められており、全ての組み合わせに従い、複数の試験対象となるプログラムが実行され、その実行の前後でメモリ使用量の計測が行われるようにしてあり、
全ての試験項目についてのプログラムの実行後に、
前記第2プロセスリストに含まれる試験項目のIDとプロセスのIDとの組み合わせ毎に件数をカウントし、
カウントした件数が所定の件数以上である場合、試験項目のIDとプロセスのIDとを対応付けて第3プロセスリストに出力する
処理を実行させる付記3又は付記4に記載のコンピュータプログラム。
(付記6)
前記第3プロセスリストに含まれるプロセスの仕様上のメモリ使用量の最大値を取得し、
前記第3プロセスリストに含まれる試験項目のIDに対応した前記プログラムの複数の入力パラメータの一つを想定される最大値に設定、前記プログラムを実行し、
前記プログラムの実行前後で、前記第3プロセスリスト含まれるプロセスのIDに対応したプロセスのメモリ使用量を計測し、
計測したメモリ使用量が、前記メモリ使用量の最大値を超えた場合に、メモリリークであると判定する付記5に記載のコンピュータプログラム。
(付記7)
前記第3プロセスリストに含まれるプロセスの仕様上のメモリ使用量の最大値が取得出来ない場合に、前記第3プロセスリストに含まれる試験項目のIDに対応した前記プログラムの複数の入力パラメータの一つを想定される最小値から最大値に適宜設定変更しながら、繰り返し前記プログラムを実行し、
前記プログラムの各実行前後で、前記第3プロセスリスト含まれるプロセスのIDに対応したプロセスのメモリ使用量を計測し、
前記プログラムの各実行前後で、前記プロセスのメモリ使用量が増大した場合に、メモリリークであると判定する付記5に記載のコンピュータプログラム。
(付記8)
コンピュータが、
試験対象となるプログラム実行前にメモリ使用量を計測し、
前記プログラムの入力パラメータを設定して前記プログラムを実行し、
前記プログラムの実行後に、メモリ使用量を計測し、
計測したメモリ使用量が前記プログラム実行前のメモリ使用量より所定値以上増加している場合、前記プログラムを再実行し、
前記プログラム再実行後に、メモリ使用量を計測し、
前記プログラム再実行後に計測したメモリ使用量が、前記プログラム再実行前のメモリ使用量より所定値以上増加しているとき、前記プログラム実行によりメモリリークの可能性ありと判定する
情報処理方法。
(付記9)
メモリ使用量を計測部と、
試験対象となるプログラムの入力パラメータを設定する設定部と、
前記プログラムを実行する実行部とを備え、
前記計測部は、前記プログラムの実行前及び実行後に、メモリ使用量を計測し、
前記プログラム実行後に計測したメモリ使用量が前記プログラム実行前のメモリ使用量より所定値以上増加している場合、前記実行部は前記プログラムを再実行し、
前記計測部は、前記プログラム再実行後に、メモリ使用量を計測し、
計測したメモリ使用量が、前記プログラム再実行前のメモリ使用量より所定値以上増加しているとき、
前記プログラム実行によりメモリリークの可能性ありと判定する判定部を
備えた情報処理装置。