对象的创建 :类加载检查 分配内存 初始化零值 设置对象头 执行 init 方法
类加载过程:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。
可作为 GC Roots 的对象包括下面几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象
本地方法栈(Native 方法)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
所有被同步锁持有的对象
不可达的对象并非“非死不可
至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。
当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行
垃圾回收
算法
标记清除,复制,标记整理,分代收集
新生代采用标记-复制算法,新生代对象大多第一次就会被回收,付出少量对象的复制成本就可以完成每次垃圾收集,
老年代的对象存活几率是比较高的,老年代采用标记-整理算法。
Serial Old 收集器,作为 CMS 收集器的后备方案,Serial 收集器对于运行在 Client 模式下的虚拟机来说是个不错的选择
吞吐量 parallel-scavenge,parallel-old
交互体验 cms,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作
(标记-清除”算法会导致收集结束时会有大量空间碎片产生,对 CPU 资源敏感,无法处理浮动垃圾),parnew 或者
G1 使用多个 CPU缩短 STW,空间整合,(整体,标记-整理,局部,标记-复制),可预测的停顿
初始标记:STW,标记gcroots, 并发标记:GC ROOTS TRACING,
重新(最终)标记,STW,修正并发标记期间因为用户程序运行而导致标记产生变动的对象, 并发清除: GC 线程开始清扫(筛选回收)
虚拟机栈 局部变量表、操作数栈、动态链接、方法出口信息
jvm内存模型 程序计数器,虚拟机栈,本地方法栈,虚拟机栈-reference->堆->方法区(类信息、常量、静态变量、即时编译器编译后的代码)(1.8移除,直接内存中的元空间替代)
线程池 fixthreadpool singlethreadpool cachedthreadpool --》
ThreadPoolExecutor coolpoolsize,maxpoolsize,workquee, kat, unit, handler,threadFactory
concurrenthashmap Node数据加链表/红黑树, 并发安全用cas+synchronized锁住链表头节点或红黑树首节点
原子类 -int自增非原子操作,AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作
java.lang.OutOfMemoryError: Java heap space 堆空间溢出,最常见的
stackoverflowError 栈空间溢出
GC overhead limit exceeded GC时间太长引发的异常
Directbuffer memory buffer 内存溢出
写NIO程序经常使ByteBuffer读取或者写入数据,这是一种基于通道(Channel)与缓冲区(Buffer)的I/0方式,
它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作
unable to create new native thread 无法创建线程
linux系统默认允许单个进程可以创建的线程数是1024个
java.lang.OutOfMemoryError: Metaspace 元空间溢出
Metaspace 不在虚拟机内存中而是使用本地内存
永久代(java8后被原空间Metaspace取代了)存放了以下信息:
虚拟机加载的类信息
常量池
静态变量
即时编译后的代码