十、Jvm结构和泄露溢出

Java不像C/C++自己掌握对象的释放,一般都是jvm包管了而内存泄露是怎么发生的呢

我们先了解一下java内存结构是怎么样的呢?

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时

间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。

我们先看看jvm内存结构吧

1. java运行时数据区域

  • 程序计数器:是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器
  • 方法区:与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  • 本地方法栈:与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务
  • Java虚拟机栈:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
  • Java堆:java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存

联想记忆:计数器-方法-本地方法-java虚拟机栈,java堆

2. 内存泄露

该被释放的资源,被某个对象所持有不能释放,导致的

2.1 主要引起内存泄露有哪些呢

  • 单例
  • 匿名内部类
  • 资源未关闭

如:

  1. Handler 引起的内存泄漏,非静态内部类,会持有外部引用,导致activity无法销毁(非静态匿名内部类对象它会自动持有外部类Activity的引用,从而导致SecondActivity无法被回收,造成内存泄漏
  2. 单例模式引起的内存泄漏(静态类持有了外部Context引用导致Activity无法销毁)
  3. 非静态内部类创建静态实例引起的内存泄漏(非静态的内部类也会持有外部引用,同时又有静态实例引用Activity,导致无法销毁)
  4. 非静态匿名内部类引起的内存泄漏
  5. 注册/反注册未成对使用引起的内存泄漏
  6. 资源对象没有关闭引起的内存泄漏
  7. 集合对象没有及时清理引起的内存泄漏

联想记忆: 非静态内部类和匿名内部类,new出来的没有置为空
具体可以看android 常见内存泄漏原因及解决办法

2.2 检查内存泄露的工具

  • Monitor工具
  • leakcanary

2.3 内存泄露的总结

其实工具都不咋好使,主要还是得靠开发人员平时多注意一下开发规范,如内部类和静态,谨慎使用,同时对于new出来的东西要自己多注意想一下什么时候会销毁,需不需要自己主动销毁一下

3. 内存溢出

当前占用的内存加上我们申请的内存资源超过了虚拟机的最分配的进程最大限制就会抛出的异常

3.1 主要体现在bitmap

解决办法:

  • 图片显示,可以使用缩略图,不用加载原图
  • 及时释放内存,使用完就立即释放
  • 图片压缩,可以使用ARGB_4444色彩质量的,也可以根据手机像素来压缩
  • inbitmap属性,3.0+的bitmap属性,支持相同尺寸的复用
  • 捕获异常

但其实内存溢出异常也是可以捕捉的

Bitmap bitmap = null;
try {
// 实例化Bitmap
bitmap = BitmapFactory.decodeFile(path);
} catch (OutOfMemoryError e) {
//
}
if (bitmap == null) {
// 如果实例化失败 返回默认的Bitmap对象
return defaultBitmapMap;
}

3.2 关于其他的会内存溢出的地方

  • listview优化
  • 避免在ondraw中执行创建对象方法
  • 谨慎使用多进程

3.3 内存溢出的总结

主要还是注意使用bitmap,毕竟这货分分钟就能溢出,就是还有注意的会重复多次调用的方法不要存在创建对象的代码!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值