gpt4 book ai didi

java - Android:释放引用后内存未释放

转载 作者:行者123 更新时间:2023-12-01 18:34:35 24 4
gpt4 key购买 nike

我有一个 Activity ,我获得了大量的对象列表,大约 25,000 个对象总共包含大约 600,000 个字符串,这占用了大约 20MB 的堆。该列表被加载到 recyclerviewadapter 中,然后显示该列表。

我的问题是,当我关闭 Activity 并且 Activity 被认为“销毁”时,庞大的对象列表不会被垃圾收集。因此,我的堆中仍然包含 20MB 的对象,当我重新打开该 Activity 时,另外 20MB 的对象会添加到堆中,内存很快就会被耗尽。

在 Activity 的 onDestroy() 方法中,我尝试释放对包含大量对象列表的 adapter 的引用。我还发布了对 recyclerViewviewModel 的引用,viewModel 是我从更新 LiveData 对象获取单词的地方适配器。

@Override
protected void onDestroy() {
adapter = null;
recyclerView = null;
viewModel = null;
Log.d("kesD", "onDestroy: pls free up my MB");
super.onDestroy();
}

尽管这不起作用,而且 20MB 的对象似乎没有从堆中删除,如下面的控制台输出所示:

(强调在销毁 Activity 并释放对象之后之前显示的57MB/81MB)

2020-02-05 20:18:36.349 2042-2077/co.uk.SpeedSpanish I/uk.SpeedSpanis: Background concurrent copying GC freed 461591(31MB) AllocSpace objects, 6(312KB) LOS objects, 29% free, 57MB/81MB, paused 151us total 238.203ms
2020-02-05 20:18:36.443 2042-2042/co.uk.SpeedSpanish D/kesD: onDestroy: pls free up my MB
2020-02-05 20:18:37.198 2042-2077/co.uk.SpeedSpanish I/uk.SpeedSpanis: Background concurrent copying GC freed 445259(31MB) AllocSpace objects, 0(0B) LOS objects, 29% free, 56MB/80MB, paused 98us total 240.906ms

我已确保不存在对 Activity 的静态引用,这可能会使其(以及我的对象列表)保持 Activity 状态。

对象列表不会在任何地方静态引用,但我确实在不同线程中使用静态方法过滤列表,如下所示:

private void getViewModelAllWords(){
viewModel = ViewModelProviders.of(this).get(WordViewModel.class);
adapter = new WordDetailedAdapter(this, viewModel, this, this, false);
viewModel.getAllWordsLive().observe(this,words -> {
Collections.sort(words, (o1, o2) -> o1.getWord().compareToIgnoreCase(o2.getWord()));
filterWords(words);
});
}

private void filterWords(List<Word> words) {
FilterThread thread = new FilterThread(words);
thread.start();
}

private class FilterThread extends Thread{

private List<Word> allWords;

public FilterThread(List<Word> allWords){
this.allWords = allWords;
}

@Override
public void run() {
if(allWords!=null){
final List<Word> words = WordFilter.getFilteredList(allWords, wordClassStr, wordCategoryStr);
runOnUiThread(() -> applyFilteredWords(words));
allWords = null;
}
}
}

private void applyFilteredWords(List<Word> words){
adapter.submitList(words);
}

@Query("SELECT * FROM Word ORDER BY word")
LiveData<List<Word>> getAllWordsLive();

我还在过滤列表后释放了对列表的引用,因此这应该不会有问题。

最佳答案

首先,当您发送一些要进行垃圾收集的内容时,它不一定会立即或一次全部被垃圾收集。

这样,您需要检查包含您的庞大列表的所有来源。在大多数情况下,它不仅固定在适配器中。

关于java - Android:释放引用后内存未释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60084136/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com