美文网首页
记录一次内存危险操作

记录一次内存危险操作

作者: ftc300_carl | 来源:发表于2017-09-05 16:50 被阅读0次

    本文属于装糊涂的猪原创,转载请注明出处作者

    背景

    自定义时钟的时候,无意间在onDraw方法中创建对象,然后就引发了内存的肆意增长,伪代码为

       @Override
        protected void onDraw(Canvas canvas) {
            method();
            invalidate();
        }
    
        private void method() {
            Calendar calendar = Calendar.getInstance();
            ...
        }
    

    学习与成长

    如何发现的呢?多亏了AndroidStudio的强大功能Android Monitor。为了更好的研究AS的这个集成功能新建了一个自定义view。

    public class CurrentTv extends TextView {
        public CurrentTv(Context context) {
            this(context, null);
        }
        public CurrentTv(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm", Locale.getDefault());
    
        public CurrentTv(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                 setText(getCurrentText());
            }
        };
    
        public void onStart(){
            handler.removeCallbacks(renderRunnable);
            handler.post(renderRunnable);
        }
    
        public void onStop(){
            handler.removeCallbacks(renderRunnable);
        }
    
    
        Runnable renderRunnable = new Runnable() {
            @Override
            public void run() {
                handler.postDelayed(renderRunnable,1000);
            }
        };
    
        private String getCurrentText() {
            Date curDate = new Date();
            return sdf.format(curDate);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            setText(getCurrentText());
        }
    
        @Override
        public void invalidate() {
            if (hasWindowFocus()) {
                super.invalidate();
            }
        }
    
    
        @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            super.onWindowFocusChanged(hasWindowFocus);
            if (hasWindowFocus) {
                invalidate();
            }
        }
    }
    

    很简单的自定义view,功能是即时在Textview上显示当前时间,但是在onDraw中创建的对象Date。于是乎,在下面的gif中粗浅的分析了一波。首先看到的是


    image.png

    Allocated不断地增长,此时点击


    image.png
    开始追踪,几秒后,再次点击 image.png

    停止追踪,稍等片刻就会生成报告。

    image.png

    同时你可以在左侧Captures中查看历史报告

    image.png

    整个操作流程如下:


    memory.gif

    参考链接:
    Allocation Tracker

    相关文章

      网友评论

          本文标题:记录一次内存危险操作

          本文链接:https://www.haomeiwen.com/subject/peoujxtx.html