垃圾回收算法
Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制。
整个回收过程分为几个阶段:找出需要回收的对象 —> 对需要回收的对象进行标记 —> 回收对象内存
前面两个阶段采用的是 根搜索算法,回收对象的的算法包含1.基础的标记-清除算法。2进阶的标记-整理算法。3.高效的复制算法,在回收过程中会根据堆的使用情况来选择合适的算法。
当应用程序空闲时,即没有应用线程在运行时,GC会被调用。因为GC在优先级最低的线程中进行,所以当应用忙时,GC线程就不会被调用
Java堆内存不足时,GC会被调用。当应用线程在运行,并在运行过程中创建新对象,若这时内存空间不足,JVM就会强制地调用GC线程,以便回收内存用于新的分配。若GC一次之后仍不能满足内存分配的要求,JVM会再进行两次GC作进一步的尝试,若仍无法满足要求,则 JVM将报“out of memory”的错误,Java应用将停止。
在编译过程中作为一种优化技术,Java 编译器能选择给实例赋 null 值,从而标记实例为可回收。
由于是否进行主GC由JVM根据系统环境决定,而系统环境在不断的变化当中,所以主GC的运行具有不确定性,无法预计它何时必然出现,但可以确定的是对一个长期运行的应用来说,其主GC是反复进行的。
GC 分为Scavenge GC和Full GC。
Scavenge GC :发生在新生代区的垃圾回收。
Full GC :对整个堆进行整理,包括Young、Tenured和Perm
Full GC因为需要对整个堆进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。以下情况会触发Full GC:
年老代(Tenured)被写满;
持久代(Perm)被写满;
System.gc()被显示调用;
上一次GC之后Heap的各域分配策略动态变化.
1. System.gc()方法
命令行参数监视垃圾收集器的运行:
使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式如下:
java -verbosegc classfile
需要注意的是,调用System.gc()也仅仅是一个请求(建议)。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生。
2. finalize()方法
概述:理解为析构方法就好,在JVM垃圾回收器收集一个对象之前,一般要求程序调用适当的方法释放资源。但在没有明确释放资源的情况下,Java提供了缺省机制来终止该对象以释放资源,这个方法就是finalize()。在finalize()方法返回之后,对象消失,垃圾收集开始执行。
意义:之所以要使用finalize(),是存在着垃圾回收器不能处理的特殊情况。假定你的对象(并非使用new方法)获得了一块“特殊”的内存区域,由于垃圾回收器只知道那些经由new分配的内存空间,所以它不知道该如何释放这块“特殊”的内存区域,那么这个时候Java允许在类中定义一个finalize()方法。
特殊的区域例如:
finalize()的主要用途是释放一些其他做法开辟的内存空间,以及做一些清理工作。因为在Java中并没有提够像“析构”函数或者类似概念的函数,要做一些类似清理工作的时候,必须override Object这个类中的finalize()方法。
注意:一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法进行一些必要的清理工作。只有到下一次再进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间。
JAVA里的对象并非总会被垃圾回收器回收。1 对象可能不被垃圾回收,2 垃圾回收并不等于“析构”,3 垃圾回收只与内存有关。也就是说,并不是如果一个对象不再被使用,是不是要在finalize()中释放这个对象中含有的其它对象呢?不是的。因为无论对象是如何创建的,垃圾回收器都会负责释放那些对象占有的内存。
当 finalize() 方法被调用时,JVM 会释放该线程上的所有同步锁。
拦截器是一个非常强大的机制,可以监视,重写和重试call(request和response)。
这样可以用来很多网络请求问题:
调用chain.proceed(request)是每个拦截器实现的一个主要部分。这个简单的方法是HTTP工作发生,产出满足请求的响应之处,
拦截器可以链接,OkHttp使用列表来跟踪拦截器,并且拦截器按顺序被调用。
##用dialog实现一个全局可自定义toast
最近有一个变态需求,做一个toast,可以点击后消失,可以在使用的时候分情况设置位置,颜色,大小。额,你确定这是我熟悉的Android的toast?光是可以点击消失就让我明白什么toast.setView()来自定义一个Toast啥的就是痴心妄想。好吧,想了想还是只有把dialog伪装一下,任重道远啊!
dialog进化为toast有几个有下面几个步骤:
Android 是基于Java的,很多时候可以用Java的思想来等同思考,但是却不能和Java程序直接一个Main函数就可以在里面随便new对象来用,像Activity,Service这些必须依靠一个context才可以创建。这是因为Android整体架构是基于组建的应用设计模式,像Activity,Service这些组件的运行需要一个完整的Android工程环境,每个组件就是这个环境中的一个场景,而Context就是这些场景的一些相关信息(也就是上下文环境)。
总结下,Context是维持Android程序中各组件能够正常工作的一个核心功能类。
当我们需要获得系统服务的时候,就会使用Context.getSystemService来获得一个对应Service 的Manager。而因为Android内部的实现,所以获得的这个Manager是一个单例。
首先,理清下getSystemService的原理,然后列出一些常用的SystemService。
在我们用普通方法对Libray Module进行打包为 test.jar,然后放到libs中使用的过程中,如果Library Module有远程依赖时,我们在使用test.jar的时候就会出现 ClassNotFoundException。因为远程依赖并没有被打包到test.jar中。
通知是Android中常用的一个消息显示方式,主要是面向用户的,但是现在部分国产手机会把新安装的app的通知权限默认关闭了,需要我们去检查是否app可以发送通知,不行的话需要通知用户去开启通知开关。
实际上在uses-permission中并没有通知权限。