收藏官网首页
查看: 10181|回复: 0

[技术分享] 从Android内存溢出的问题,证明Android加密内存保护的重要性...

6

主题

9

帖子

178

积分

注册会员

Rank: 2

积分
178
跳转到指定楼层
楼主
发表于 2017-12-29 14:54:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
教您5分钟接入机智云,实现傻瓜式开发
Android 的虚拟机是基于寄存器的 Dalvik,它的最大堆大小一般是16M,有的机器为 24M。(备注:Android 5.0及后续Android版本中作为正式的运行时库这里不做讨论可参考一招教你读懂JVMDalvik之间的区别)因此我们所能利用的内存空间是有限的。如果我们的内存占用超过了一定的水平就会出现OutOfMemory 的错误。
内存溢出的几点原因:
1. 资源释放问题
程序代码的问题,长期保持某些资源,如 ContextCursorIO 流的引用,资源得不到释放造成内存泄露。
垃圾回收机制
垃圾回收(garbage collection,简称GC)可以自动清空堆中不再使用的对象。在JAVA中对象是通过引用使用的。如果再没有引用指向该对象,那么该对象就无从处理或调用该对象,这样的对象称为不可到达(unreachable)。**垃圾回收用于释放不可到达的对象所占据的内存。
实现思想:我们将栈定义为root,遍历栈中所有的对象的引用,再遍历一遍堆中的对象。因为栈中的对象的引用执行完毕就删除,所以我们就可以通过栈中的对象的引用,查找到堆中没有被指向的对象,这些对象即为不可到达对象,对其进行垃圾回收。
如果持有对象的强引用,垃圾回收器是无法在内存中回收这个对象。
2. 对象内存过大问题
保存了多个耗用内存过大的对象(如 BitmapXML 文件),造成内存超出限制。
3.static 关键字的使用问题
static Java 中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用 static 修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费
过多的实例(Context 的情况最多),这时就要谨慎对待了。
以上的代码是很危险的,如果将 Activity 赋值到 mContext 的话。那么即使该 Activity 已经
onDestroy,但是由于仍有对象保存它的引用,因此该Activity 依然不会被释放。
我们举 Android 文档中的一个例子。
sBackground 是一个静态的变量,但是我们发现,我们并没有显式的保存 Contex 的引用,但是,当 Drawable View 连接之后,Drawable 就将 View 设置为一个回调,由于 View 中是包含 Context 的引用的,所以,实际上我们依然保存了 Context 的引用。这个引用链如下:
Drawable->TextView->Context
所以,最终该 Context 也没有得到释放,发生了内存泄露。
针对 static 的解决方案
1) 应该尽量避免 static 成员变量引用资源耗费过多的实例,比如 Context
2) 使 WeakReference 使 WeakReferencemContextRef;
3) Context 尽量使用ApplicationContext,因为 Application Context 的生命周期比较长,引用它不会出现内存泄露的问题。
4. 线程导致内存溢出
线程产生内存泄露的主要原因在于线程生命周期的不可控。我们来考虑下面一段代码。
这段代码很平常也很简单,是我们经常使用的形式。我们思考一个问题:假设 MyThread run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,一般情况下当屏幕转
换时会重新创建 Activity,按照我们的想法,老的 Activity 应该会被销毁才对,然而事实上并非如此。
由于我们的线程是 Activity 的内部类,所以 MyThread 中保存了 Activity 的一个引用,当MyThread run 函数没有结束时,MyThread 是不会被销毁的,因此它所引用的老的 Activity
不会被销毁,因此就出现了内存泄露的问题。
有些人喜欢用 Android 提供的 AsyncTask,但事实上 AsyncTask 的问题更加严重,Thread 只有在 run 函数不结束时才出现这种内存泄露问题,然而 AsyncTask 内部的实现机制是运用ThreadPoolExcutor,该类产生的 Thread 对象的生命周期是不确定的,是应用程序无法控制的,因此如果 AsyncTask 作为 Activity 的内部类,就更容易出现内存泄露的问题。
针对这种线程导致的内存泄露问题的解决方案:
(一)将线程的内部类,改为静态内部类(因为非静态内部类拥有外部类对象的强引用,而静态类则不拥有)。
(二)在线程内部采用弱引用保存 Context 引用。
几个不错的内存泄漏检测工具
利用Android StudioMonitor进行内存泄漏检查
LeakCanary
BlockCanary
Android安全现状
由于Android开源的环境,导致Android的整体环境都存在很多不安全的因素,同时用户在移动APP客户端的便捷应用,也给用户带来了巨大的安全隐患。未经过安全加固的APP存在被静态反编译、恶意篡改、二次打包、动态钓鱼攻击等多个安全隐患。静态破解可让黑客直接逆向出客户端所有的功能代码、加密算法以及与服务器通信的相关方法及URL等敏感信息。黑客可以随意进行恶意代码注入、篡改欺骗用户甚至攻击服务器;动态攻击可让黑客进行相关敏感数据的窃取,如用户核心账户信息、服务器端相关信息等。
Android加密重要性
针对Andriod加密,几维安全平台提供了内存保护、完整性保护、反调试保护、源码保护、字符串加密、资源文件校验、自定义Lua解析器、SO文件保护等功能的加固保护服务。
针对企业级定制的国内首个移动代码虚拟化方案“KiwiVM”,深度代码混淆,高级动态防护,帮助移动厂商解决核心模块,专利算法,金融通信等场景的顶级防护。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表