上一篇
一下停下来写博客就又鸽了这么久,真的人生就像打陀螺,一旦你不抽打,它就会不转,一旦它停下,那就有大麻烦了!人生苦短,希望能在年轻的时候,把自己想做的事情做好,做的整整齐齐,做的心里舒服。
上一篇文章写到了 JVM 的运行时数据区域、垃圾回收机制及算法,虽然 Java 的面试可能会多一点,但是能够掌握下也是有点帮助的,至少涨了信心。接下来继续把 JVM 剩下的总结了,主要就是 JVM 的内存模型和垃圾收集的策略,很遗憾我没有系统的拜读就 Java 虚拟机这本书,以后有机会吧,这里真的就是简单的总结了。
八、内存模型
这里就用某资料的图来说明了,主要就是四个部分。
- Eden 区:新生代
- 大多数情况,对象在 Eden 区分配
- Eden 空间不足时会 Minor GC
- Minor GC 后,Eden 会被清空,存活对象进入 From 区
- 如果 From 区不够,直接进入 Old 区
- Survivor 区:
- 缓冲,每次 Minor GC 后,会将 From 存活对象放到 Survivor 区(不够进 Old -> 空间分配担保)
- 减少被送到老年代的对象,Survivor 筛选经过几次 Minor GC 对象到 Old
- Old 区
- 只有 Major GC 才会进行清理,内存越大 stop the world 越久
- 使用标记-整理算法,会多次复制,效率很低
九、Minor GC 和 Full GC
-
Minor GC:回收新生代,频繁执行,速度较快
-
Full GC:回收老年代和新生代,很少执行,执行速度慢
触发条件:
- 调用 System.gc()
- 老年代空间不足
- 空间分配担保失败
- JDK 1.7前永久代空间不足(记前三个吧)
- Concurrent Mode Failure
十、内存分配策略
- 优先在 Eden 分配
- 大对象直接进老年代
- 长期存活对象进入老年代
- 动态对象年龄判定:
- 相同年龄所有对象大小总和大于 Survivor 空间一半
- 年龄大于或等于该年龄的对象可以直接进入老年代
- 空间分配担保:
- Minor GC 之前先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果成立则是安全的
- 如果允许担保失败会处理,否则就进行 Full GC
十一、类加载机制
-
类是在运行期间第一次使用时动态加载的,而不是一次性加载
-
类的生命周期(2、3部分写的比较简单,如有需要,可自行看资料):
-
生命周期:
加载 -> 验证 ->准备 ->解析 ->(<->交换顺序实现动态绑定) 初始化 ->使用 ->卸载
-
加载过程:前五个
-
初始化阶段才是真正执行雷总定义的 Java 程序代码
-
-
类初始化时机
- 主动引用(触发初始化):new、反射、子类触发父类、执行主类(包含main方法)、JDK 1.7 动态语言支持
- 被动引用(不触发):子类引用父类静态、定义引用类数组、常量池的类
-
类与类加载器
-
两个类相等,需要类本身相等,并且使用同一个类加载器进行加载
-
加载器分类
-
启动器加载器:BootStrapClassLoader,加载 rt.jar 的 JDK 文件,所有加载器父类
-
扩展类加载器:ExtClassLoader,加载 jre/lib/ext 目录
-
应用程序类加载器:AppClassLoader,System 类加载器,加载 classpath
如果应用程序没有自定义过自己的加载器,一半使用 AppClassLoader
-
-
工作原理:
- 委托机制:加载任务委托交给父类加载器,如果不信就向下传递委托任务,由其子类加载器加载,保证 Java 核心库的安全性。
- 可见性机制:子类加载器可以看到父类加载器加载的类,反之不行
- 单一性机制:父类加载器加载过的类不能被子加载器加载第二次
-
下一篇
到这里 Java 的内容就告一段落了,接下的是计算机网络相关的内容,大概六篇,再后面是安卓基础、进阶及其他。