前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM基本结构及内存模型及优化

JVM基本结构及内存模型及优化

作者头像
攻城狮的那点事
发布2019-10-03 13:54:25
5190
发布2019-10-03 13:54:25
举报

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。作为一个Java开发者,这是必须要掌握的知识点。

一,JVM的基本结构

JVM启动后,对操作系统来说,JVM是一个的进程,这个进程的基本结构如上图所示。它包括:

  • 类加载器子系统
  • 运行时数据区
  • 执行引擎

运行时数据区是JVM从操作系统申请来的堆空间和操作系统给JVM分配的栈空间的总称。也是JVM内存结构所在位置。

二,JVM的内存模型

根据java虚拟机规范,java虚拟机管理的内存将分为下面五大区域。分为:虚拟机栈,堆,方法区,程序计数器,本地方法栈。

1,程序计数器

是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果是Natice方法,则为空。

2,Java 虚拟机栈

它是线程私有的。每个方法在执行的时候也会创建一个栈帧,存储了局部变量,操作数,动态链接,方法返回地址。每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈。通常所说的栈,一般是指在虚拟机栈中的局部变量部分。局部变量所需内存在编译期间完成分配,如果线程请求的栈深度大于虚拟机所允许的深度,则StackOverflowError。如果虚拟机栈可以动态扩展,扩展到无法申请足够的内存,则OutOfMemoryError。

3,本地方法栈

线程私有,和虚拟机栈类似,主要为虚拟机使用到的Native方法服务。也会抛出StackOverflowError 和OutOfMemoryError。

4,方法区

被所有方法线程共享的一块内存区域。用于存储已经被虚拟机加载的类信息,常量,静态变量等。这个区域的内存回收目标主要针对常量池的回收和堆类型的卸载。

5,堆内存

堆是JVM内存占用最大,管理最复杂的一个区域。唯一的途径就是存放对象实例:所有的对象实例以及数组都在堆上进行分配。jdk1.7以后,字符串常量从永久代中剥离出来,存放在堆中。堆具有进一步的内存划分。即新生代和老年代,划分如下图所示:

按照GC分代收集的角度堆内存划分:

  • 老年代:2/3的堆空间
  • 年轻代:1/3的堆空间
  • eden区:8/10 的年轻代
  • survivor0: 1/10 的年轻代
  • survivor1: 1/10的年轻代

堆内存中的内存分配:

  • 清理年轻代:minor GC;
  • 清理老年代:major GC;
  • 清理整个堆空间:full GC;

堆内存中年轻代和老年代的内存分配及使用规则:

1,新创建的对象主要分配在年轻代的Eden区;

被new的对象优先分配到年轻代的Eden区,如果Eden区没有足够大小的连续内存空间分配时,Jvm就会触发一次minor GC,经过minor GC回收存活下来的对象被分配到Survivor区,如果Survivor区不够安置,Jvm会通过“空间分配担保机制”提前转移对象到老年代。

2,大对象直接进入老年代

那些需要大量连续内存空间的对象,如数组或很长的字符串,大小超过虚拟机提供的阙值-XX:PretenureSizeThreshold(默认值为0)时,对象直接分配到老年代,避免在新生代Eden和两个Survivor区之间发生大量的内存复制(新生代采用复制算法进行垃圾回收)。

3,年轻代长期存活的对象会被晋升到老年代

虚拟机内存回收时,为了能够识别哪些对象该继续留在新生代(Survivor区),那些对象应该转移到老年代,它给每个对象定义了一个年龄计数器。每当对象在Survivor区的From<--->To区复制一次,年龄计数器就+1,对年龄超过 -XX:MaxTenurigThreshold设置的值时,对象被转移到老年代。对象年龄最大值为15。注意,这里不是所有对象的年龄都到设置的阙值才转移,当Survivor区空间内存不足时,对象也会提前进去老年区。

4,动态对象年龄判断

虚拟机不是永远等到对象年龄达到阙值后才转移到老年代。当Survivor中相同年龄的所有对象的大小总和大于Survivor的一半时,那些年龄大于等于此相同年龄的所有对象将会直接提前进入老年区。

注:-XX:MaxTenurigThreshold未设置时,默认为15。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 攻城狮的那点事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档