Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android循环可运行增加堆_Java_Android_Heap Memory - Fatal编程技术网

Java Android循环可运行增加堆

Java Android循环可运行增加堆,java,android,heap-memory,Java,Android,Heap Memory,我在Android中创建了一个简单的活动,可以无限运行循环。堆将一直增加,直到抛出GC_并发。这是正常行为还是应该改变编码方式 代码如下: public class MainActivity extends Activity implements Runnable { private final Handler mHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanc

我在Android中创建了一个简单的活动,可以无限运行循环。堆将一直增加,直到抛出GC_并发。这是正常行为还是应该改变编码方式

代码如下:

public class MainActivity extends Activity implements Runnable {

    private final Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler.postDelayed(this, 100);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(this);
    }

    @Override
    public void run() {
        TextView textView = (TextView)findViewById(R.id.text_id);
        textView.setText(R.string.hello_world);

        TextView textView2 = (TextView)findViewById(R.id.text_id2);
        textView2.setText(R.string.hello_world);

        TextView textView3 = (TextView)findViewById(R.id.text_id3);
        textView3.setText(R.string.hello_world);

        mHandler.postDelayed(this, 100);
    }
}

所以我有3个文本视图,我只想调用一个runnable来更新显示的文本(这里我放置了资源字符串,但它可以是任何字符串)。当我旋转平板电脑时,我没有看到内存泄漏(为此,我应该使用WeakReference或删除onDestroy()上的回调)。我只是不明白为什么堆在增加,而没有GCed。一旦runnable被执行,它应该被垃圾收集,如果UI刷新速度超过100ms,堆应该停止增加

谢谢你的帮助,
JB

“我在这里放置了资源字符串,但它可以是任何字符串”——这可能会对内存消耗产生很大影响。“一旦runnable被执行,它应该被垃圾收集”--不,因为您正在立即重新注册它。顺便说一句,您不需要
处理程序
,因为您可以在任何
文本视图
对象上调用
postdayed()
。“我只是不明白堆为什么在增加”——仅仅因为您没有在这里显式地创建Java对象并不意味着像
setText()
这样的调用中的框架没有创建Java对象。这就是为什么您需要真正理解框架,而不是仅仅使用它们,盲目地希望它们能够工作。此外,你不应该假设某个东西一未使用就会被GCD——它几乎永远不会被使用。关键是它将在稍后的某个时间被清理,可能是几分钟甚至几天。这就是为什么Java没有真正的析构函数。下次GC想要清理时,它将被清理。假设它永远不会被清理比假设它会被及时清理更安全。此外,我可以告诉你,setText绝对会在框架中创建需要GCed的对象,postHandler可以(如果消息池用完,或者如果一个bug阻止了消息对象的回收)。事实上,postHandler造成了太多问题,以至于他们重用了消息对象,而不是动态地分配它们并让它们被gced。我认为最好有一个静态的内部类来实现Runnable并保存对外部活动的WeakReference。很难像您所写的那样编写代码,也很难不泄露当前可以做到的上下文(活动)。好的,非常感谢您的回答。我将研究setText()的代码,以了解它是如何工作的。Gabe如果我无法预测GC何时发生,那么等待堆填满直到GC_并发,因为最终它不会使我的应用程序崩溃,这是不是很糟糕?