Skip to content

Instantly share code, notes, and snippets.

@todesking
Created January 21, 2011 04:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save todesking/789242 to your computer and use it in GitHub Desktop.
Save todesking/789242 to your computer and use it in GitHub Desktop.
明示的な開放を必要とするリソースが正しく開放されたかチェックする
/* 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