美文网首页
小知识点(一)android

小知识点(一)android

作者: 胖胖O蓝胖子 | 来源:发表于2018-10-11 11:28 被阅读0次

    Bitmap 使用时候注意什么?

    1.不要在主线程中处理处理图片。

    2.高效加载大的图片,BitmapFactory类提供了一些加载图片的方法:decodeByteArray(), decodeFile(), decodeResource(), 等等。为了避免占用较大内存,经常使用BitmapFactory.Options 类,设置inJustDecodeBounds属性为true。

    为了避免java.lang.OutOfMemory 的异常,我们在真正decode图片之前检查它的尺寸,除非你确定这个数据源提供了准确无误的图片且不会导致占用过多的内存。需要压缩采用BitmapFactory.Options 中设置 inSampleSize 为true 。例如, 一个分辨率为2048x1536 的图片,如果设置inSampleSize 为4,那么会产出一个大概为512x384的图片。

     为了保证使用的资源能被回收,建议使用WeakReference(弱引用,保证能被gc回收)

    android中内存泄露和内存溢出

    泄露:gc无法回收应该回收的对象。

    过多的内存泄露最终会导致内存溢出,同时频繁的gc会导致UI卡顿。

    溢出:Android为每个进程设置Dalvik Heap Size阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如果APP想要分配的内存超过这个阈值,就会发生OOM。

    只要allocated + 新分配的内存 >= dalvik heap 最大值的时候就会发生OOM。

    ActivityManager.getMemoryClass()可以查询当前APP的Heap Size阈值,单位是MB。

    避免泄露的方法:

    1.使用轻量的数据结构:例如:ArrayMap,SparseArrary等。

    2.不要使用枚举。

    3.bitmap采用压缩和缓存。

    4.不使用string拼接,如果需要可以使用Stringbuilder或Stringbuffer。

    5.使用静态内部类。

    6.慎重使用匿名内部类(会对外部有隐式的引用)。

    7.context持有原因:对于大部分非必须使用Activity Context的情况(创建Dialog的Context必须是Activity Context),应该使用Application Context。

    8.销毁监听器。

    9.资源文件需要选择合适的文件夹进行存放:hdpi/xhdpi/xxhdpi等等不同dpi的文件夹下的图片在不同的设备上会经过scale的处理。例如我们只在hdpi的目录下放置了一张100100的图片,那么根据换算关系,xxhdpi的手机去引用那张图片就会被拉伸到200200。需要注意到在这种情况下,内存占用是会显著提高的。对于不希望被拉伸的图片,需要放到assets或者nodpi的目录下。

    10.关闭无用的链接。

    11.合理使用static对象。

    12.单例模式中谨慎使用外部的引用。

    13.使用LeakCanary内存检测工具,查看内存泄露。


    JVM、Dalvik以及ART的区别Android开发——JVM、Dalvik以及ART的区别 - xj326138716的博客 - CSDN博客


    Dalvik是Google公司自己设计用于Android平台的虚拟机。

    jvm是Google公司自己设计用于java程序运行的虚拟机平台。

    2014年Google用ART代替Dalvik。

    Activity横竖屏切换时的生命周期

    不配置android:configChanges

    onPause -->onSaveInstanceState -->onStop -->onDestroy -->onCreate-->onStart -->

    onRestoreInstanceState-->onResume -->onPause -->onStop -->onDestroy        

    配置:置android:configChanges="orientation|keyboardHidden|screenSize"  则都不会调用Activity的其他生命周期方法,只会调用onConfigurationChanged方法。


    jvm内存模型

    运行时区内存模型:

    私有部分:


    程序计数器:
    由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切 换 之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰。

    java栈:Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表操作数栈、指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant pool)、方法返回地址和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。

    本地方法栈:本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。

    公有部分:

    堆:Java中的堆是用来存储对象本身的以及数组(数组引用是存放在Java栈中的)。堆是被所有线程共享的,在JVM中只有一个堆。

    方法区:与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

    溢出情况如图:

    双亲委派模型Java 类加载机制(阿里面试题)-何时初始化类 - aspirant - 博客园

    类加载器 Java 类如同其它的 Java 类一样,也是要由类加载器来加载的;除了启动类加载器,每个类都有其父类加载器(父子关系由组合(不是继承)来实现),所谓双亲委派是指每次收到类加载请求时,先将请求委派给父类加载器完成(所有加载请求最终会委派到顶层的Bootstrap ClassLoader加载器中),如果父类加载器无法完成这个加载(该加载器的搜索范围中没有找到对应的类),子类尝试自己加载。

    个人认为这也是java只能单继承的原因。(若不对请指出)

    GC回收算法:

    常见回收算法

    1、标记-清除算法:

    标记阶段:先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象;

    清除阶段:清除所有未被标记的对象。

    2、复制算法:(新生代的GC)

    将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,然后清除正在使用的内存块中的所有对象。

    3、标记-整理算法:(老年代的GC)

    标记阶段:先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象

    整理阶段:将将所有的存活对象压缩到内存的一端;之后,清理边界外所有的空间

    4、分代收集算法:

    存活率低:少量对象存活,适合复制算法:在新生代中,每次GC时都发现有大批对象死去,只有少量存活(新生代中98%的对象都是“朝生夕死”),那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成GC。

    存活率高:大量对象存活,适合用标记-清理/标记-整理:在老年代中,因为对象存活率高、没有额外空间对他进行分配担保,就必须使用“标记-清理”/“标记-整理”算法进行GC。

    res目录和assets目录的区别?

    未完待续..............

    相关文章

      网友评论

          本文标题:小知识点(一)android

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