-
jstack dump日志文件中的状态
DeadLock: 死锁,多个线程相互循环竞争资源,导致都无法释放资源的情况
Runnable: 线程获取CPU资源,运行代码逻辑
Waiting on Condition : 等待某个资源,或者等待触发的条件。
Blocked: 线程阻塞,失去资源,常见的情况就是等待资源超时。
waiting for monitor entry: 等待获取监视器
-
java内存模型
-
java内存组成部分
栈:java虚拟机栈和本地方法栈 线程私有
StackOverFlowError:当线程请求的栈深度大于虚拟机栈设置的深度,报此错误
OutOfMemoryError: 当虚拟机栈动态扩展时,无法申请到足够的空间时,报此错误
堆:线程共享 年轻代: eden : survivor from : survivor to : old 8:1:1 老年代 持久代
方法区: 所有线程共享,用户存放已经被虚拟机加载的类信息、常量、静态变量等信息
程序计数器:线程私有的
对象创建过程
1. 类加载检查 2. 对象分配内存 3. 并发处理 4. 内存空间初始化 5. 对象设置 6. 执行init()
类加载检查
JVM遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用是否已经被加载、解析和初始化。
对象分配内存
对象所需要的内存的大小在类加载完成后便完全确定,然后在堆中分配对应大小的内存。
java堆内存分配的两种方式:
1.指针碰撞:Java堆中的内存是规整的,一分为二,通过一个指针分开,内存分配时,把指针从指向空闲的位置移动到用过的内存那边,例如:Serial、ParNew等收集器
2. 空闲列表:虚拟机中维护一张列表,记录堆中各个块的分配情况。例如:CMS基于Mark-Sweep算法的收集器。
并发处理
1.使用CAS 2.TLAB本地线程分配缓冲
内容空间初始化
将分配的地址空间分配为初始值
对象设置
虚拟机把对象的实例、类的元数据信息、分代年龄等信息进行设置
GC的两种判断方法
1. 引用计数器 2. 跟搜索算法(可作为GC Root的对象有:虚拟机栈引用的对象、方法区中静态属性引用的对象、方法区常量引用的对象、本地方法栈中引用的对象)
Java对象的四种引用
强引用 软引用 弱引用 虚引用
GC的收集方法
标记-清除算法(内存碎片) 复制算法(内存浪费一半) 标记-整理算法
GC算法
Serial串行收集器
Parallel并行收集器
CMS并发标记收集器
G1垃圾收集器
Minor GC回收年轻代 Major GC回收永久代 Full GC包括年轻代和老年代
静态分派与动态分派
静态分派:重载, 依赖静态类型来定位方法执行版本的分派动作
动态分派:重写, 编译阶段发生,运行期根据实际类型确定方法执行版本
双亲委派模型
除了顶层的启动类加载器外,其他的类加载器应该都有自己的父类
BootstrapClassLoader JAVA_HOME/lib
ExtensionClassLoader JAVA_HOME/lib/ext
ApplicationClassLoader classpath
常用的内存调试工具
jmap jstack jconsole