看书记一下关键信息,怕自己忘了,断断续续看了一两遍。
二.正文 第二部分 自动内存管理机制- 在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OOM的可能。(p50)
- HotSpot虚拟机中,对象在内存中的存储分为三部分:对象头Header,实例数据Instance Data和对齐填充Padding。对象头又分为两部分:第一部分存储自身运行时数据包括HashCode,GC分代年龄,锁状态等,这部分叫MarkWord;第二部分是类型指针,虚拟机通过这个指针确定这个对象是哪个类的实例。(p47)
- 关于OOM,堆溢出的情况:不断地创造对象,且保证Gc roots 到这些对象可达,这些对象不会被清除,当对象数量达到堆最大容量限制就会出现OOM。这种情况最常见。(p51)
- HotSpot虚拟机不区分虚拟机栈和本地方法栈,栈容量仅由-Xss参数设置。(p53)
- 虚拟机栈中,有两种异常:StackOverFlowError:线程请求的栈深度大于虚拟机所允许的最大深度时抛出;OOM:虚拟机栈在扩展过程中无法申请到足够的内存空间。
- 方法区和运行时常量池溢出:jdk1.7之前,常量池被分配在永久代(方法区),后来jdk1.7之后去掉了永久代的概念(永久代就是一个概念,hotSpot JVM专属,方法区是它的实现)。
第三部分 垃圾收集器与内存分配策略
- 即便gc-roots标记为不可达,对象也不是必须死的。还需要两个标记过程,第一次标记:对象在可达性分析中被发现没有引用,此时被标记且进行一次筛选,条件是**“这个对象有没有必要执行finalize()方法”**,(如果对象没有覆写finalize方法或者finalize()方法已经被调用过了,那么被视为没必要执行)。如果没必要执行,那么这个对象就死了会被回收
如果这个对象被判定为有必要执行finalize()方法,对象会被放在一个F-queue中,等待虚拟机创建一个Finalizer线程去执行它。会触发,但为了防止finalize()方法执行太慢,不会等待它执行结束。
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-queue中的对象进行第二次小规模标记,如果对象想要拯救自己----------就需要重新与gc-roots引用链的对象建立关联,如果此时对象还没有建立连接,那么这个对象就会被回收。
- 方法区回收的效率很低,一般回收两种东西,第一种是没人用的常量,第二种是废弃的class。



