【发布时间】:2016-10-21 19:06:53
【问题描述】:
我有一个简单的应用程序,它收集和显示 Wifi 扫描结果,并带有一些额外的功能,不会占用大量 CPU/RAM。
问题是当我的线程正在运行时(此线程扫描并通过 ExpandableListView 输出结果),我的内存一次平均被填满 70Mb。
我在查看我创建的对象被清除后存在的内存转储时注意到。
例如我已经实现的一个简单示例
private ExpandableListAdapter returnList(Context context, String[] APList) {
if (bLogging) { //Assume true
ArrayList<String> List = new ArrayList<>();
foreach (AccessPoint ap: APList){
//code initilializing and assigning param variables
List.add(new AP(param1, param2, param3))
}
return (new ExpandableListAdapter(context, List));
}
}
请不要担心任何语法等问题,这只是为了理解我的问题。
这段代码是由Thread运行的,每隔500ms就休眠重新扫描
在本例中,returnList() 执行完毕后,ArrayList<> List、new AP(param...) 将保留为对象,占用内存。
我的线程循环定义为:
//code before
t = new Thread(new Runnable() {
public void run() {
handler = new Handler(context.getMainLooper());
while (!bStopThread) {
ThreadCounter++;
handler.post(new Runnable() {
@Override
public void run() {
if (bSafe) {
initWiFiArrays(); //AccessPoint Objects are created as shown in example
CreateSetAdapter(); //Custom ExpandableListAdapter is created, but declared and instantiated within the method
threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
writeResultsToFile();
} else
stopScan();
}
});
try {
Thread.sleep(scanInterval);
} catch (Exception x) {
x.printStackTrace();
}
}
}
});
t.start();
//code after
更新:
我求助于清除全局声明的列表和包含 +/- 9 个项目的 scanResultCollection,这减少了 40Mb 占用的内存。
【问题讨论】:
-
当您的
return语句中引用了List时,为什么它们不保留在内存中? -
抱歉,如果我误解了,但是java有垃圾收集,因为这个方法已经完成了它的目的,它会被清理,这在我容易访问的意义上它不会“不在内存中”它。
-
您正在“泄露”您的
local变量到外部范围。虽然有一个对象的 live 引用,但它不是垃圾回收的对象。 -
好的,所以在第一次运行时,会有一个局部变量“out”,但是在第二次和第三次会发生什么,等等。这个“live”是否不会将其指针替换为创建的局部变量的第二次和第三次运行。换句话说,第一次运行的时候,它的父级得到一个新对象时不会被收集吗?
标签: java android memory memory-management out-of-memory