标签:ide orm new t eclips void port 不能 ret 内部类
public class Test {
static ArrayList<Person> list = new ArrayList<Person>();//list中引用的对象在应用整个生命周期中都不会被释放
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
Person person = new Person("" + i);
list.add(person);
person = null;//将变量person指向null,而不是指向堆内存中的Person对象;注意这时堆内存中的Person对象并没有被回收
}
for (Person person : list) {
System.out.println(person);//所有Person对象都没有被回收!!!
}
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class Test { public static void main(String[] args) { B b = new B();//被监听者,如Activity A a = new A();//监听者,如BroadcastReceiver b.register(a);//在b中注册【a监听器】,通常register内部的操作是:将a的引用传给b的成员变量,进而长期持有a的引用 a = null;//虽然将监听器a设为null,但是监听器对象A并没有被回收,因为它被B引用了 b.show();//监听器工作了 b.unregister();//用完要注销掉 } }
interface Listener { public void listen(); }
class A implements Listener {//监听者,如BroadcastReceiver @Override public void listen() { System.out.println("监听器工作了"); } }
class B {//被监听者,如Activity Listener listener; public void register(Listener listener) {//B持有了Listener的引用,除非在B内部将其设为null,否则listener将不会被回收 this.listener = listener; } public void unregister() { listener = null; } public void show() { if (listener != null) listener.listen(); } }
/**
* 测试非静态内部类导致内存泄漏的问题
*/
public class MemoryLeaksActivity extends Activity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView = new TextView(this);
setContentView(textView);
String startTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
textView.setText("开始休息 " + startTime);
new Thread(() -> {
SystemClock.sleep(1000 * 5);
String endTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
Log.i("bqt", "【结束休息】" + endTime);//即使Activity【onDestroy被回调了】,这条日志仍会打出来
//runOnUiThread(() -> textView.append("\n结束休息 " + endTime));
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("bqt", "【onDestroy被回调了】");
}
}
/**
* 测试使用静态内部类避免导致内存泄漏
*/
public class MemoryLeaksActivity extends Activity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textView = new TextView(this);
setContentView(textView);
String startTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
textView.setText("开始休息 " + startTime);
new MyThread(this).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("bqt", "【onDestroy被回调了】");
}
private static class MyThread extends Thread {
SoftReference<Activity> context;
MyThread(Activity activity) {
context = new SoftReference<>(activity);
}
@Override
public void run() {
SystemClock.sleep(1000 * 15);
String endTime = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
Log.i("bqt", "【结束休息】" + endTime);//即使Activity【onDestroy被回调了】,这条日志仍会打出来
if (context.get() != null) {
context.get().runOnUiThread(() -> Toast.makeText(context.get(), "结束休息", Toast.LENGTH_SHORT).show());
}
}
}
}
标签:ide orm new t eclips void port 不能 ret 内部类
原文地址:http://www.cnblogs.com/baiqiantao/p/7425220.html