Created
January 21, 2011 04:30
-
-
Save todesking/789242 to your computer and use it in GitHub Desktop.
明示的な開放を必要とするリソースが正しく開放されたかチェックする
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This program is free software. It comes without any warranty, to | |
* the extent permitted by applicable law. You can redistribute it | |
* and/or modify it under the terms of the Do What The Fuck You Want | |
* To Public License, Version 2, as published by Sam Hocevar. See | |
* http://sam.zoy.org/wtfpl/COPYING for more details. */ | |
/** | |
* 明示的な開放が必要なリソースクラスが使用する。 | |
* | |
* finalizeメソッドにより、開放されていないリソースがあった場合標準エラー出力に警告を出す。 | |
* | |
* usage: リソースの準備ができた段階で ResourceLeakChecker.create(getClass())、 | |
* リソースが開放された段階でsetClosed()を呼ぶ。 | |
* assertionが有効になっている場合、setClosed()が呼ばれないとGC時に警告メッセージを表示。 assertion無効時は何もしない | |
* | |
* <pre> | |
* {@code | |
* class UnmanagedResource { | |
* public UnmanagedResource() { | |
* this.handle=OuterSystem.getResource(); | |
* checker=new ResourceLeakChecker.create(getClass()); | |
* } | |
* private final int handle; | |
* private final ResourceLeakChecker checker; | |
* | |
* public void close() { | |
* OuterSystem.releaseResource(handle); | |
* checker.setClosed(); | |
* } | |
* } | |
* </pre> | |
*/ | |
public abstract class ResourceLeakChecker { | |
public static ResourceLeakChecker create(Class<?> klass) { | |
if (isAssertionEnabled()) | |
return new Impl(klass); | |
else | |
return new Null(); | |
} | |
private static boolean isAssertionEnabled() { | |
try { | |
assert false; | |
} catch (AssertionError e) { | |
return true; | |
} | |
return false; | |
} | |
public abstract void setClosed(); | |
private static class Null extends ResourceLeakChecker { | |
@Override | |
public void setClosed() { | |
} | |
} | |
private static class Impl extends ResourceLeakChecker { | |
private Impl(Class<?> klass) { | |
try { | |
throw new Exception("Resource leak detected at " | |
+ klass.getName()); | |
} catch (Exception e) { | |
this.error = e; | |
} | |
} | |
private final Exception error; | |
private boolean closed = false; | |
@Override | |
public void setClosed() { | |
this.closed = true; | |
} | |
@Override | |
protected void finalize() throws Throwable { | |
if (!closed) { | |
error.printStackTrace(System.err); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment