jvm内存结构

根据jvm规范,jvm内存分为虚拟机栈、堆、方法区、程序计数器、本地方法栈
image.png

java8和Java7的区别

方法区的实现,Java7方法区的实现是永久代,Java8方法区的实现是元空间。

方法区Java8之后的变化:

  • 移除元空间,替换为永久代
  • 永久代中的类元信息转移到本地内存
  • 永久代中的字符串常量池和类静态变量转移到了堆
  • 永久代参数变为元空间参数

将永久代替换为元空间原因:

  • 字符串在永久代,容易出现性能问题和内存溢出
  • 类及方法信息比较难确定大小,对于永久代的大小制定比较困难
  • 永久代会提高gc复杂度,并且回收率偏低

程序计数器

线程私有
存放的是将要执行指令的地址。

虚拟机栈

线程私有

  • 虚拟机栈

和线程同时创建,用于存储栈帧。
每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表操作数栈动态链接方法出口等信息

  • 栈帧(Stack Frame)

用于支持虚拟机进行方法调用和方法执行的数据结构。
存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
大小设置:
-Xss1m
-Xss1024k
-Xss1048576

  • 局部变量表
  • 操作数栈
  • 动态链接
  • 方法返回地址

本地方法栈

类似于虚拟机栈,
区别:虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机执行本地方法服务

堆的概念

线程共享

几乎所有对象都在这里分配内存
例外:逃逸分析技术

  • 设置堆空间的大小

-Xmx20m -Xms5m

  • 堆的分类

image.png

年轻代和老年代

  1. JVM中存储java对象可以被分为两类:
  • 年轻代:主要存放新创建的对象,内存相对较小,垃圾回收较频繁。年轻代分成1个Eden Space和2个Suvivor Space(from 和to)
  • 年老代:主要存放JVM认为生命周期比较长的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁。
  1. 配置新生代和老年代堆结构占比
  • 默认 -XX:NewRatio=2 , 标识新生代占1 , 老年代占2 ,新生代占整个堆的1/3

修改占比 -XX:NewPatio=4 , 标识新生代占1 , 老年代占4 , 新生代占整个堆的1/5

  • Eden空间和另外两个Survivor空间占比分别为8:1:1

可以通过操作选项 -XX:SurvivorRatio 调整这个空间比例。 比如 -XX:SurvivorRatio=8

对象分配过程

分配过程
1.new的对象先放在伊甸园区。该区域有大小限制
2.当伊甸园区域填满时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园预期进行垃圾回收(Minor GC),将伊甸园区域中不再被其他对象引用的额对象进行销毁,再加载新的对象放到伊甸园区
3.然后将伊甸园区中的剩余对象移动到幸存者0区
4.如果再次触发垃圾回收,此时上次幸存下来的放在幸存者0区的,如果没有回收,就会放到幸存者1区
5.如果再次经历垃圾回收,此时会重新返回幸存者0区,接着再去幸存者1区。
6.如果累计次数到达默认的15次,这会进入养老区。
可以通过设置参数,调整阈值 -XX:MaxTenuringThreshold=N
7.养老区内存不足是,会再次出发GC:Major GC 进行养老区的内存清理
8.如果养老区执行了Major GC后仍然没有办法进行对象的保存,就会报OOM异常.

堆GC

GC分两种:

  • 部分收集器(partial GC)
    • 新生代收集(minor GC/yong GC):只是新生代的垃圾收集
    • 老年代收集(major GC/old GC):只是老年代的垃圾收集
    • 混合收集(mixed GC):收集整个新生代及老年代的垃圾收集(G1 GC)
  • 整堆收集器(Full GC):收集整个Java堆和方法区的垃圾收集器

触发条件:

  • 年轻代GC:年轻代空间不足
  • 老年代GC:老年代空间不足,速度比minor GC慢10倍以上
  • fullGC:调用System.go(),系统会执行full GC,不是立即执行

方法区

线程共享
用于存储已被jvm加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据

元空间、永久代是方法区具体的落地实现。方法区看作是一块独立于Java堆的内存空间,它主要是用来存储所加载的类信息的

Java8以后,设置元空间大小:
元数据区大小可以使用参数 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize指定
默认值依赖于平台。windows下,-XX:MetaspaceSize是21M,-XX:MaxMetaspaceSize的值是-1,即没有限制。

运行时常量池

常量池vs运行时常量池

字节码文件中,内部包含了常量池
方法区中,内部包含了运行时常量池
常量池:存放编译期间生成的各种字面量与符号引用
运行时常量池:常量池表在运行时的表现形式

直接内存