java-jvm-1

82 阅读2分钟

JVM MAIN

内存结构

stack

程序计数器

查看class字节码

// jdk
javap -c xx.class
// idea plugins in github
// view -> show bytecode with Jclasslib
Jclasslib
  1. 每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期一致
  2. 内存很小,可忽略
  3. 没有OOM

java栈

// 出入参: 都是引用,且被封装,便于拓展
// 对象内部变量域: 全是引用
xxxResponse func(xxxRequest){
  // 方法内尽量使用基本类型
  int,long
}
  1. 每个线程在创建的时候都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次 Java 方法调用,是线程私有的,生命周期和线程一致
  2. 栈是一种快速有效的分配存储方式
  3. 在这个线程上正在执行的每个方法都各自有对应的一个栈帧
  4. 栈不存在垃圾回收问题
  5. 会StackOverflowError(Error)

本地栈

  • 本地方法是使用C语言实现的, native

heap

  • 栈是运行时的单位,而堆是存储的单位。

YG=e+s0+s1

  1. Minor GC
  2. YG:OG=1:2(3份)
  3. e:s0:s1=8:1:1(10份)

OG

  1. Major GC
  2. FullGC = Minor + Major

TLAB

Thread Local Allocation Buffer-XX:UseTLAB;

  1. 从内存模型而不是垃圾回收的角度,对Eden区域继续进行划分,JVM为每个线程分配了一个私有缓存区域,它包含在 Eden空间内.
  2. 一旦对象在 TLAB 空间分配内存失败时,JVM 就会尝试着通过使用加锁机制确保数据操作的原子性,从而直接在Eden空间中分配内存

逃逸分析

(Escape Analysis),通过逃逸分析,Java Hotspot 编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。 (从stack逃逸到heap)

metaspace

  1. PG: jdk7
  2. metaspace:jdk8
  3. 方法区

GC

内存模型

类加载

字节码

ClassLoader

.java => .class => load => link => init

生命周期

加载的机制

key

引用类型