手机回收

手把手带你了解内存抖动和泄漏的优化

主宰稳场 提交于 2019-12-16 02:05:45
前言 这个系列的文章: 1、用通俗易懂的讲解方式,讲解一门技术的实用价值 2、详细书写源码的追踪,源码截图,绘制类的结构图,尽量详细地解释原理的探索过程 3、提供Github 的 可运行的Demo工程,但是我所提供代码,更多是提供思路,抛砖引玉,请酌情cv 4、集合整理原理探索过程中的一些坑,或者demo的运行过程中的注意事项 5、用gif图,最直观地展示demo运行效果 如果觉得细节太细,直接跳过看结论即可。本人能力有限,如若发现描述不当之处,欢迎留言批评指正。 学到老活到老,路漫漫其修远兮。与众君共勉 !,和我一起当个CV工程师吧,手动滑稽 正文大纲 jvm内存管理常识 检测以及处理内存抖动 检测以及处理内存泄漏 正文 jvm内存管理常识 LMK (LowMemoryKill)机制 android底层会在系统内存告急的时候,按照一定规则杀死一些进程来满足其他进程的内存需要。其中 消耗内存的高低就是其中一项指标,所以,优化app的内存占用,能够有效降低app被系统杀死的概率。 GC STW机制 GC,垃圾回收进程,在 GC 线程执行任务的时候,会存在一个 STW (stop the world) 机制,他就会把其他所有线程都挂起。如果 GC 非常频繁地调用,那就会导致主线程不流畅,给用户的感觉就是 卡顿。 内存抖动频繁引起OOM 内存抖动太频繁,导致大量对象频繁创建和销毁

jvm(十一):垃圾收集器

六眼飞鱼酱① 提交于 2019-12-06 16:51:31
总的来说,Java 虚拟机的垃圾回收器可以分为四大类别: 串行回收器、并行回收器、CMS 回收器、G1 回收器。 串行回收器 串行回收器是指使用单线程进行垃圾回收的回收器。因为每次回收时只有一个线程,因此串行回收器在并发能力较弱的计算机上,其专注性和独占性的特点往往能让其有更好的性能表现。 串行回收器可以在新生代和老年代使用,根据作用于不同的堆空间,分为新生代串行回收器和老年代串行回收器。 新生代串行回收器 串行收集器是所有垃圾回收器中最古老的一种,也是 JDK 中最基本的垃圾回收器之一。 在新生代串行回收器中使用的是复制算法。在串行回收器进行垃圾回收时,会触发 Stop-The-World 现象,即其他线程都需要暂停,等待垃圾回收完成。因此在某些情况下,其会造成较为糟糕的用户体验。 使用 -XX:+UseSerialGC 参数可以指定使用新生代串行收集器和老年代串行收集器。当虚拟机在 Client 模式下运行时,其默认使用该垃圾收集器。 老年代串行回收器 在老年代串行回收器中使用的是标记压缩算法。其与新生代串行收集器一样,只能串行、独占式地进行垃圾回收,因此也经常会有较长时间的 Stop-The-World 发生。 但老年代串行回收器的好处之一,就是其可以与多种新生代回收器配合使用。若要启用老年代串行回收器,可以尝试以下参数: -XX:UseSerialGC :新生代

JVM垃圾回收机制

余生长醉 提交于 2019-12-06 14:27:36
什么是垃圾回收机制 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制。 什么时候进行垃圾回收     1.会在cpu空闲的时候自动进行回收;     2.在堆内存存储满了之后;     3.主动调用System.gc()后尝试进行回收; 如何判断对象可以被回收   堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)   引用计数法     给对象添加一个引用计数器,每当有一个地方引用,计数器加1。当引用失败,计数器就减1。任何时候计数器为0的对象就是不可能再被使用的。     这个方法实现简单,效率高,但是目前主流的虚拟机中没有选择这个算法来管理内存,最主要的原因是它很难解决对象之前相互循环引用的问题。所谓对象之间的相互引用问题,例如,除了对象A和B相互引用这对象之外,这两个对象之间再无任何引用。但是它们因为相互引用对方,导致它们的引用计数器都不为0,于是引用计数器无法通知GC回收它们。          可达性分析算法     这个算法的基本思想就是通过一系列的称为"GC Roots"的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链的话

今天是JVM的生日,来了解下JVM的发展历史吧

血红的双手。 提交于 2019-12-05 19:43:43
1991年4月,由James Gosling主导的团队创造了Oak语言,java的前身,1995年5月23号,Oak语言更名Java,并且提出那句注明的:”write Once,Run Anywhere”的口号.1996年1月23日,JDK1.0发布. 当时正好赶上浏览器快速崛起,发展的浪潮,大家发现java一处编译到处使用的特性和浏览器很契合,同一个页面不可能每一个操作系统我都写一遍.用现在的话说java正好站在这个风口上.导致它飞速发展才有了今天的江湖地位. 一、JVM简介 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。 Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后

Java虚拟机总结

て烟熏妆下的殇ゞ 提交于 2019-12-05 19:39:59
思维导图: 一、Java引用的四种状态: 强引用:   用的最广。我们平时写代码时,new一个Object存放在堆内存,然后用一个引用指向它,这就是强引用。   如果一个对象具有强引用,那垃圾回收器绝不会回收它 。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 软引用:   如果一个对象只具有软引用,则内存空间足够时,垃圾回收器就不会回收它;如果 内存空间不足了,就会回收这些对象的内存 。(备注:如果内存不足,随时有可能被回收。)   只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。 弱引用:   弱引用与软引用的区别在于: 只具有弱引用的对象拥有更短暂的生命周期 。    每次执行GC的时候 ,一旦发现了只具有弱引用的对象, 不管当前内存空间足够与否,都会回收它的内存 。不过,由于垃圾回收器是一个优先级很低的线程,因此 不一定会很快发现那些只具有弱引用的对象 。 虚引用:   “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同, 虚引用并不会决定对象的生命周期 。如果一个对象仅持有虚引用,那么它就和没有任何引用一样, 在任何时候都可能被垃圾回收器回收 。   虚引用主要用来跟踪对象被垃圾回收器回收的活动。 二、Java中的内存划分:

垃圾回收器及tomcat调优

匿名 (未验证) 提交于 2019-12-03 00:08:02
1 、概述:垃圾回收机制, Java 中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存。 内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着。该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下, Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离 1 、特别注意一些像 HashMap 、 ArrayList 的集合对象,它们经常会引发内存泄漏。当它们被声明为 static 时,它们的生命周期就会和应用程序一样长。 2 、特别注意事件监听和回调函数。当一个监听器在使用的时候被注册,但不再使用之后却未被反注册。 3 、如果一个类自己管理内存,那开发人员就得小心内存泄漏问题了。” 通常一些成员变量引用其他对象,初始化的时候需要置空。 Java 技术使用 finalize ()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize ()方法以整理系统资源或者执行其他清理工作。 finalize ()方法是在垃圾收集器删除对象之前对这个对象调用的。 引用计数法 概述

剖析 JVM 相关知识点(中)

匿名 (未验证) 提交于 2019-12-02 23:47:01
标记清除算法 复制算法 标记整理算法 分代收集算法 1. 标记清除算法 :将所有需要回收的对象进行标记,标记结束后对标记的对象进行回收。 缺点 是效率低,会造成大量的碎片。 2. 复制算法 :复制算法将空间分为两部分,每次使用其中的一部分。当一块内存用完了,就将这块的所有对象复制到另一块,将已使用的块清除。 优点 :不会产生碎片, 缺点 :会浪费一定的内存空间。 在堆中的年轻代使用该算法 ,因为年轻代的对象多为生存周期比较短的对象。 年轻代将内存分为一个 Eden,两个 Survivor。每次使用 Eden 与一个 Survivor。当回收时,将 Survivor 与 Eden 中存活的对象复制到另一个 Survivor,最后清理掉 Eden 与 Survivor。当 Survivor 与 Eden 中存活的对象大小超过另一个 Survivor,则需要老年代来担保。 3. 标记整理算法 : 缺点 :复制算法在对象存活率较高时,复制会使得效率降低。根据老年代的特点,使用标记整理算法。标记之后将所有存活的对象移向一端,将其他的整理。 优点 :解决了碎片问题。 4. 分代收集算法 :年轻代、老年代根据各自不同的特点采用不同的算法。 以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 Serial 翻译为串行,也就是说它以串行的方式执行

深入理解Java虚拟机

匿名 (未验证) 提交于 2019-12-02 21:53:32
引用计数法 高效率,但无法解决循环引用的问题,Python语言在使用 可达性分析 主流商用程序语言在使用,比如C#,Java,以及Lisp。通过一系列被称为GC Roots的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为 引用链 。当一个对象到GC Roots没有任何引用链相连,对象不可达的,则证明此对象是不可用的,会被判定为可回收的对象。 作为GC Roots的对象有以下几种: 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中类静态属性引用的对象 方法区中常量引用的对象 本地方法栈JNI(也就是Native方法)引用的对象 引用 Strong Reference: 最常用的方式 Soft Reference: 会在发生内存溢出之前,会把这些对象列入回收范围,进行二次回收。 Weak Reference: 被弱引用关联的对象只能生存到下一次垃圾收集发生之前。 PhantomReference: 最弱的一种引用关系,是否有虚引用存在,不对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。唯一作用是在这个对象被收集器回收时收到一个系统通知。 回收过程 被标记为不可达对象,处于一种缓刑阶段,正式回收前,至少要经历两次标记过程。 第一次被标记为不可达,会进行一次筛选,条件是对象是否有必要执行finalize方法(没有执行过finalize方法并且覆盖过这个方法)

android Bitmap的内存优化

邮差的信 提交于 2019-11-30 15:53:25
在Android应用里,最耗费内存的就是图片资源。而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常。所以,对于图片的内存优化,是Android应用开发中比较重要的内容。 1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收。这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间。那为什么还需要这个方法呢? Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap。仔细查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通过JNI调用方式实现的。所以,加载Bitmap到内存里以后,是包含两部分内存区域的。简单的说,一部分是Java部分的,一部分是C部分的。这个Bitmap对象是由Java部分分配的,不用的时候系统就会自动回收了,但是那个对应的C可用的内存区域,虚拟机是不能直接回收的,这个只能调用底层的功能释放。所以需要调用recycle()方法来释放C部分的内存。从Bitmap类的源代码也可以看到,recycle()方法里也的确是调用了JNI方法了的。

android service被系统回收的解决方法

家住魔仙堡 提交于 2019-11-30 11:34:12
android service被系统回收的解决方法 博客分类: Android开发 android service kill 自己的app的service总是容易被系统回收,搜罗了一下,基本上的解决思路有以下几种: 1.把service写成系统服务,将不会被回收(未实践): 在Manifest.xml文件中设置persistent属性为true,则可使该服务免受out-of-memory killer的影响。但是这种做法一定要谨慎,系统服务太多将严重影响系统的整体运行效率。 2.提高service的优先级(未实践): 设置android:priority="1000" Xml代码 <!-- 为了消去加上android:priority="1000"后出现的警告信息,可以设置android:exported属性,指示该服务是否能够被其他应用程序组件调用或跟它交互 --> < service android:name = "com.example.helloandroid.weatherforecast.service.UpdateWidgetService" android:exported = "false" > <!-- 为防止Service被系统回收,可以通过提高优先级解决,1000是最高优先级,数字越小,优先级越低 --> < intent-filter android