JVM内存结构

java内存模型图:

JVM内存结构_第1张图片
jvm内存模型粗略得可以分为三个部分:堆内存,方法区,堆栈(线程私有)。
有些地方会把方法区归为堆内存,但实际上方法区还有另一个名字叫(非堆),也会被称为永久代(但实际上也会存在GC),不过java8已经把方法区移到了元空间,存在于本地内存。
堆内存可以分为新生代区和老生代区,而新生代区有Eden,From Survivor,To Survivor(8:1:1)。

参数配置图解:
JVM内存结构_第2张图片
-Xms 最小堆内存
-Xmx 最大堆内存
-XX:NewSize 最小新生代内存
-XX:MaxNewSize 最大新生代
-XX:PerSize 最先永久代内存
-XX:MaxPerSize 最大永久代呢村
-Xss: 单个线程栈内存大小

JVM与系统之间得关系图:
JVM内存结构_第3张图片

类加载机制

  • 类加载过程:当java文件被编译后,生成的.class文件会被类加载器加载到运行时数据区,然后执行链接的步骤,包含对字节码内容进行验证,初始化分配做准备(设置默认值),当该类被实例化时,则先执行初始化。
  • 最终结果:java文件被编译成.class文件,类加载器把字节码文件加载到运行时数据区,并在堆中创建类的相关java.lang.Class对象,用来封装类在方法区的数据结构。jvm根据根据在这些数据运行程序。
  • 类加载器:java的类加载器概括来说包含两种,启动加载器和其他加载器;启动加载器是虚拟机的一部分由c语言实现,他可以负责加载其他加载器的class。
  • 双亲委派模型:类加载器存在继承关系时,当前类加载器会讲需要加载的目标传递给父类加载器,当父类不能加载时,则就近加载;确保内存中只存在一份字节码数据!

堆内存

作用:存储程序中所有对象实例数据和类的Class对象(如上所说)的区域,为所有线程之间共享。
结构:堆内存会被分有新生代和老生代,老生代又可以分为伊甸区,FromSpace, ToSpace,其中不同区域对应的垃圾回收算法也会不同。

jvm中的垃圾回收算法:
标记清除-对于可回收的对象先标记再清除,效率高;适用于新生代对象更新频繁,从而会留下更多大块的内存区域。
标记整理-先标记,清除再整理,相比标记清楚,多了整理的步骤,所以适用于老生代不会频繁调用回收机制。
复制算法:将内存分为两块区域,轮流替换使用。不适合对象存活周期长的区域,频繁的复制会大大降低回收效率
分代回收算法:根据内存特征选择不同的回收算法

方法区

用途:保存的是被虚拟机加载的类信息,常量,静态变量等编译后的代码信息。也是线程共享区域。
方法区的特点是对象的回收率低,存活周期长。因此,不适合使用复制算法回收
jdk1.8使用元空间代替方法区,元空间也不存在在虚拟内存中,而是使用的实际物理内存。

程序计数器

用途:记录每个线程执行指令位置,为线程私有。
程序计数器在内存中只会占用一小块内存,用于线程专门记录指令执行位置,当CPU在线程之间进行切换的时候,便于线程恢复到相应的位置。

栈内存

用途:栈内存是线程私有,每开启一个新线程都会创建一块该线程所私有的内存。
a栈内存模拟了线程开始执行方法到结束的过程模型,
b线程没执行一个方法都会创建一个栈帧,栈帧保存了方法中的局部变量,方法出口等信息。
栈帧所分配的内存在编译期间就确定了。
异常:
1,当线程请求的站深度超过了jvm所规定的深度,则会抛出栈溢出异常。意思是线程调用方法深度超过了虚拟机规定的深度。
2,当线程无法申请到扩充栈的内存失败时,会抛出内存溢出

你可能感兴趣的:(JAVA,jvm,jvm内存,堆栈)