Cycle Finder ツール

使用状況

Foo と Bar の 2 つのクラスを循環する簡単な例を以下に示します。

cat Foo.java
package mypkg;
public class Foo {
  Bar myBar;
}

cat Bar.java
package mypkg;
public class Bar {
  Foo myFoo;
}

cycle_finder Foo.java Bar.java
acceptAST: mypkg/Bar.java
acceptAST: mypkg/Foo.java

***** Found reference cycle *****
Bar -> (field myFoo with type Foo)
Foo -> (field myBar with type Bar)
----- Full Types -----
Lmypkg/Bar;
Lmypkg/Foo;

1 CYCLES FOUND.

出力には、まず、解析対象の各 Java ファイルの acceptAST が表示されます。これは単なる情報ロギングです。

サイクルごとに 2 つのリストが出力されます。最初のリストには、サイクルの説明が含まれています。参照グラフの各行はエッジを示します。エッジの説明には、オリジンのタイプと、そのオリジンタイプがターゲット タイプをどのように参照するかの説明が表示されます。

Full Types の下にある 2 つ目のリストには、サイクル内の各タイプに固有の型キーが表示されます。各タイプの完全なパッケージが提供されるため、便利です。

リストを抑制

検出された周期の一部については、是正措置は必要ありません。これは、サイクルに、割り当てを解除する必要のない長期間有効なオブジェクトが含まれていることが原因である可能性があります。あるいは、ツールでは、関係するオブジェクトが周期を形成しないことが証明可能な場合、特定のフィールドのタイプに基づいて理論的な周期を検出できます。このような場合、suppress-list ファイルを使用して、これらのサイクルを報告しないようにできます。

このツールでは、--suppress-list オプションを使用して抑制リスト ファイルを使用できます。抑制リスト ファイルは、1 行のエントリを含む書式なしテキスト ファイルです。抑制リストのエントリは、以下の例に示す 4 つの形式のいずれかを使用します。正当なサイクルを抑制しないように、抑制リストのエントリを追加するときは、できるだけ具体的に指定することをおすすめします。コメントは「#」文字を使用して追加できます。

# Specifies that "fieldA" in ClassA will not refer to any object that is a subtype of ClassB.
FIELD my.pkg.ClassA.fieldA my.pkg.ClassB

# Suppresses all cycles containing "fieldA" in ClassA.
FIELD my.pkg.ClassA.fieldA

# Suppresses all cycles containing any field of ClassA.
TYPE my.pkg.ClassA

# Suppress all cycles containing the Inner's outer reference to ClassA.
OUTER my.pkg.ClassA.Inner

# Suppress all cycles containing the outer reference from an anonymous class declared in myMethod.
OUTER my.pkg.ClassA.myMethod.$

# Suppresses all cycles containing any type in package "my.pkg".
NAMESPACE my.pkg