现在快手字节跳动等公司都在大量招人,薪资优厚,但是想进去却没那么简单,面过的人都知道,这些公司的面试官巴不得把你会的东西都给你挖出来,所以要深入复习知识点,让自己耐问一点。一下是针对内存泄露真实面试过程:

1.什么是内存泄漏

内存泄漏是指程序申请内存之后,无法释放已经申请的内存,也就是该回收的对象不能被回收。一般是持有引用的对象生命周期比该引用生命周期长导致。

2.哪些场景导致内存泄漏

资源对象没有关闭导致内存泄漏,比如广播没有反注册,EventBus没有反注册,文件流没有关闭,数据库指针没有关闭,bitmap用完之后没有回收。

static修饰的成员变量或者单例模式,比如static修饰的context,由于被修饰的对象生命周期和app一样长,可能会导致activity无法被回收。

在非静态内部类中持有静态实例。因为非静态累默认持有外部类的实例,当持有静态实例的时候会导致内部类生命周期和app一样长,从而导致外部类的生命周期也和app一样长而无法被回收。只要把非静态内部类改成静态内部类即可。

3.内存溢出会有什么影响

一次两次内存泄漏出不会造成什么影响,但是内存泄漏多了会导致系统不断发生gc从而导致程序卡顿,同时内存泄漏多了可能会导致系统分配的内存不够用而发生内存溢出crah。

4.如何检测内存泄漏

mat分析内存
集成leakcanery检测内存泄漏
androidstudio lint静态代码检测内存泄漏

5.请描述mat分析内存的过程

在程序运行的时候再as上打开profiler,然后选择memory,在手机上操作,比如关闭对应的activity,然后点击as上的GC,点击dump,一般来说as就可以自动分析hprof文件,整理出对应的内存信息,可以选择按包排序,然后选择我们的程序,看看那些对象还在使用内存,如果应该被回收的对象却还在使用内存,说明已经发生内存泄露了。

然后如果不想在AS上分析,也可以导出hprof文件,去eclipse中找到mat进行分析,但是mat不能识别hprof文件需要使用hprof-conv命令进行转换,命令是hprof-conv 源文件 输出文件,之后就可以使用mat进行内存分析了。

其中最主要的两个工具是Histogran可以看到不同类型buffer数量和占用内存大小,Dominator Tree把对象按照内存大小进行排序,然后我们可以通过merge shortest paths to gc roots,然后选择引用关系,就可以看到究竟是哪内存泄露了。

6.leakecanery的原理了解吗

如果我们想监听一个对象是否被回收,可以采用weakreference和referencequeue的结合的方式进行。我们在构造weakreference的时候传入一个referencequeue实例,当weakreference引用的对象被回收的时候,他会被存在pending内,然后会有个线程无线循环读取这个pending队列,这个weakreference会被添加到这个referencequeue中,这时候我们可以查找referencequeue队列,如果里面有这个weakreference,则说明对应的对象被回收了。

在leakcanery初始化的时候会注册app的lifecycleCallbacks,当activity执行ondestroy的时候leakcanery会收到回调,并拿到对应的activity的引用,此时会调RefWatcher的watcher方法,在这个方法里会通过AndroidWatcherExcetor启动一个Runnable任务,在这个任务中会用构建keyedweakreference,并传入activity对象和referencequeue的实例,并且这个任务会延迟5秒之后再执行。

当activity被回收时,keyedweakreference会被加入referencequeue中,如果发生内存泄漏,则referencequeue无法找到keyedweakreference对象,此时可以判断发生了内存泄漏。所以在这个任务中,会调用ensureGone方法去referencequeue查找是否有keyedweakreference对象,如果有则说明发生了内存泄露,activity没有被回收。则会再次调用GC方法再回收一次,如果此时referencequeue中仍fan没有keyedweakreference的对象,则说明肯定存在内存泄露,则通过heapDumper分析prof文件,并通过heampdumplister回调结果到通知栏。

7.leakecanery具体是如何判断有没有发生内存泄露的呢?

刚才说过,当WeakReference里传入ReferenceQueue的时候,如果WeakReference内持有的对象引用被回收,则会把WeakReference对象添加到ReferenceQueue队列中。利用这个原理,leakcanary在监听到activity执行onDestroy的时候会构建一个keyedWeakReference实例,这个keyedWeakReference继承自weakReference,里面包含key和name字段

构建keyedWeakReference实例的时候会随机生成一个key,传进去,也就是这个弱引用对象和这个key是绑定的。同时,会把这个key存入到Set retainedKeys中。当执行ensureGone方法的时候会先去keyedWeakReference队里中查找WeakReference对象,如果存在,则说明已经回收成功,则从retainedKeys中移除对应的key,然后再检验retainedKeys中是否还存有该WeakReference.key,如果不存在了,则说明已经成功回收,如果还存在,则说明没有成功回收,此时出发一次GC,再走一遍刚才的流程,如果仍然存在key,则说明确定发生内存泄露了。上面讲到,检测内存泄露的任务延迟了5秒钟,已经给足了回收的时间,如果此时都不能被回收掉,说明activity肯定发生了内存泄露。

8.检测内存泄露的任务发生在哪个线程?

通过Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler())
等待主线程空闲的时候发送到子线程中,并延迟5秒。

9.什么叫内存溢出

内存溢出就是程序在申请内存的时候系统可用内存或者系统分配的内存不够了导致发生oom异常。如果内存溢出得多了就会导致内存溢出。

10.内存溢出一般发生在就JVM哪个区

JVM中程序技计数器,虚拟机栈,本地方法栈都是随线程生,随线程灭,帧栈随方法进入和退出做了入栈和出栈处理,实现了内存自动清理,所以内存溢出一般会发生在堆区和方法区,其中堆区用于堆区用于存放对象的实例,是垃圾收集器的主要管理区域,并且分代管理对象;方法区一般存放虚拟机加载的类信息,常量,静态变量,编译后的代码和数据,GC主要回收方法区的常量和类卸载。这两个区域都可能发生内存溢出.

这些都是常见的面试题,我整理出来分享给大家。此外我还把Github上8.3k星的Android性能优化教程和实战项目整合成了一个PDF文档。

资料全部整理下来有722页,涵盖设计思想与代码质量优化、程序性能优化、开发效率优化、Github高星优化实战项目解析,其中详细讲解了启动优化、布局优化、内存优化、屏幕适配、OOM问题等方面。有兴趣的朋友【点击我】免费获取。

Github高星优化实战项目解析

1.启动速度
2.流畅度
3.抖音在APK包大小资源优化的实践
4.优酷响应式布局技术全解析
5.网络优化
6.手机淘宝双十一性能优化项目揭秘
7.高德APP全链路源码依赖分析
8.彻底干掉OOM的实战经验分享
9.微信Android终端内存优化实践

设计思想与代码质量优化

1.六大原则.
2.设计模式
3.数据结构
4.算法

程序性能优化

1.启动速度与执行效率优化
2.布局检测与优化
3.内存优化
4.耗电优化
5.网络传输与数据储存优化
6.APK大小优化
7.屏幕适配
8.OOM问题原理解析
9.ANR问题解析
10.Crash监控方案

开发效率优化

1.分布式版本控制系统Git
2.自动化构建系统Gradle

由于资料内容太多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容,有需要的朋友记得点赞支持下哦,【点击我】免费领取!

字节跳动、快手等大厂Android面试刨根问底之内存泄露篇的更多相关文章

  1. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  2. Android handler 可能会造成内存泄露

    Android handler 可能会造成内存泄露 Android Studio 使用 Handler 时: private Handler handler = new Handler(){ @Ove ...

  3. Android使用Handler造成内存泄露的分析及解决方法

    一.什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用 ...

  4. 我把阿里、腾讯、字节跳动、美团等Android性能优化实战整合成了一个PDF文档

    安卓开发大军浩浩荡荡,经过近十年的发展,Android技术优化日异月新,如今Android 11.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS. 但是,到了各大厂商手 ...

  5. 可怕!字节跳动大牛爆出的“Android进阶指南”,强到无法形容,GitHub已标星“8.5k”!

    前言 从去年8月份开始,我开始重新找工作,在这期间刷了不少面试题和大牛博客,无意中薅到一份字节跳动大牛整理的一份"Android进阶指南",包含Android面试常见问题.主流技术 ...

  6. 2018最新大厂Android面试真题

    前言 又到了金三银四的面试季,自己也不得不参与到这场战役中来,其实是从去年底就开始看,android的好机会确实不太多,但也还好,3年+的android开发经历还是有一些面试机会的,不过确实不像几年前 ...

  7. 被字节跳动、小米、美团面试官问的AndroidFramework难倒了? 这里有23道面试真题,助力成为offer收割机!

    目录 1.Android中多进程通信的方式有哪些?a.进程通信你用过哪些?原理是什么?(字节跳动.小米)2.描述下Binder机制原理?(东方头条)3.Binder线程池的工作过程是什么样?(东方头条 ...

  8. 2021大厂Android面试高频100题最新汇总(附答案详解)

    前言 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是前后端.移动开发,好像都得刷题,这么多人通过刷题过了面试,说明刷题对于找工作还是有帮助的. 不过这其中有一个问题 ...

  9. [Android Memory] App调试内存泄露之Context篇(下)

    转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用A ...

随机推荐

  1. Redis配置统计字典

    本章将对Redis的系统状态信息(info命令结果)和Redis的所有配置(包括Standalone.Sentinel.Cluster三种模式)做一个全面的梳理,希望本章能够成为Redis配置统计字典 ...

  2. 9、mysql的备份与恢复

    mysql中 /*! ....*/ 不是注释,mysql为了保持兼容,它把一些特有的仅在mysql上用的语句放在/*!....*/中, 这样这些语句如果在其他数据库中是不会被执行,但在mysql中它会 ...

  3. nacos服务注册,ClientWorker狂刷日志的问题

    日志,启动项目就疯狂的刷ClientWorker日志 配置 本身项目中配置的依赖 nacos-discovery,nacos-config版本都是2021.1,但是编译版本是1.4.1 升级nacos ...

  4. vim程序编辑器---常用操作整理

    vim程序编辑器---常用操作整理 移动光标方法 o 在光标行的下一行,进入编辑模式 $ 移动到光标这行,最末尾的地方 G(大写) 移动到文件最末行 :set  nu 文件显示行数 :set  non ...

  5. Ionic命令笔记

    Ionic命令:ionic serve 开启服务调试ionic cordova prepare android 生成android原生项目 ionic cordova run browser 打包成混 ...

  6. cron表达式详解(转)

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: (1) Seconds Minutes Hours DayofMonth Mo ...

  7. dp 套 dp扯谈

    1.[扯谈概念] \(dp\) 套 \(dp\) 其实也就是 \(dp\) . 这里就定义下面两个概念: 内层 \(dp\) 表示的是被套在里面的那个 \(dp\) 外层 \(dp\) 表示的是最外面 ...

  8. PYTHON 连接SQL2008 导出到EXCEL

    #import pymssql from datetime import datetime import pyodbc import os current_dir = os.path.abspath( ...

  9. File类与常用IO流第三章IO流概述

    一:以内存为基准,按照数据的流动方向,流向内存为输入(读取数据),流出内存为输出.IO流有四大顶级父类: IO流四大顶级父类   输入流 输出流 字节流 字节输入流 InputStream 字节输出流 ...

  10. Redux-基本概念

    相关文档 1)         英文文档: https://redux.js.org/ 2)         中文文档: http://www.redux.org.cn/ 3)         Git ...