JVM模型介绍

JVM模型介绍

1.JVM 为什么使用元空间替换了永久代?

这里引入知乎
码上技术指导老师-回答
点击超链接,可以查看原文。

这里我对原文做一些自己的提炼,用自己的话说明白即可。

(1)JDK 7 之前JVM模型

可以看到,堆和方法区物理上是连接在一起的,但是逻辑运行层面是隔离的。
在这里插入图片描述
我们绝大多数用的虚拟机是Hotspot版本的虚拟机,其结构如下:

  1. 堆和方法区是物理连续而不是逻辑运行连续
  2. 方法区位于永久代之中
  3. 永久代和堆是逻辑上隔离的,物理上连续的,同1。
    在这里插入图片描述
    Java 7 → Java8 中数据存储位置转移如下:
  4. 符号引用——Native Memory
  5. 字符串常量池——Java Heap
  6. 类的静态常量——Java Heap(JDK 7)——元空间(JDK 8)
  • 永久代参数:(只在JDK7以及之前生效)
    -XX:PermSize -XX:MaxPermSize
  • 年轻代参数:
    -Xmn:

题目:
在这里插入图片描述

这里显然指的是JDK7,
-Xms 堆内存的初始大小,默认为物理内存的1/64。一般来讲,大点,程序会启动的快一点。
-Xmx 堆内存的最大大小,默认为物理内存的1/4。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。
-Xmn 堆内新生代的大小,其中包含1个Eden区2个Suvivor区,通过这个值也可以得到:

老年代的大小 = -Xmx减去-Xmn

-Xss 设置每个线程可使用的内存大小,即栈的大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。

解析:
最小内存值是-Xms 所以是1024M
-XXSurvivorRatio=3
1个Eden : 1个Suvivor = 3 : 1
而Survivor区有2个,所以总共占用5份内存空间,-Xmn是堆内新生代的大小,那么5120M是新生代的总大小,Suvivor = (5120 / 5) * 2 = 2048M
所以答案是D

(2)JDK 8 之后JVM模型

HotSpots取消了永久代,方法区存在于元空间(Metaspace)。同时,元空间不再与堆连续,而且是存在于本地内存(Native memory)。
在这里插入图片描述
我们知道当堆内存空间不够时会触发GC垃圾回收,但是Native memory空间不够却不会触发GC。
在这里插入图片描述
-XX:MetaspaceSize,class metadata的初始空间配额,以bytes为单位,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当的降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize(如果设置了的话),适当的提高该值。
-XX:MaxMetaspaceSize,可以为class metadata分配的最大空间。默认是没有限制的。
-XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为class metadata分配空间导致的垃圾收集。
-XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为class metadata释放空间导致的垃圾收集。

(3)总结

  1. 表面上看是为了避免OOM异常。因为通常使用PermSize和MaxPermSize设置永久代的大小就决定了永久代的上限,但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。
  2. 更深层的原因还是要合并HotSpot虚拟机和JRockit虚拟机的代码,JRockit从来没有所谓的永久代,也不需要开发运维人员设置永久代的大小,但是运行良好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java虚拟机(JVM)内存模型JVM用于管理Java程序运行时内存的一种机制。JVM将内存划分为不同的区域,每个区域都有自己的用途和生命周期。这些区域包括: 1. 程序计数器(Program Counter Register):程序计数器是一块较小的内存区域,它用于记录当前线程所执行的字节码指令的地址。每个线程都有一个独立的程序计数器。 2. Java虚拟机栈(Java Virtual Machine Stacks):Java虚拟机栈是线程私有的,它用于存储Java方法执行时的局部变量、操作数栈、动态链接、方法出口等信息。 3. 本地方法栈(Native Method Stack):本地方法栈与Java虚拟机栈类似,但是它是为本地方法服务的。 4. Java堆(Java Heap):Java堆是Java虚拟机管理的内存中最大的一块。Java对象实例和数组都在堆上分配内存。堆是所有线程共享的一块内存区域。 5. 方法区(Method Area):方法区是用于存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 6. 运行时常量池(Runtime Constant Pool):运行时常量池是方法区的一部分,用于存放编译器生成的字面量和符号引用。 7. 直接内存(Direct Memory):直接内存不是JVM运行时数据区的一部分,但是它也可以被JVM所管理。在使用NIO(New IO)时,可以使用直接内存来提高IO性能。 以上就是JVM内存模型的主要区域。JVM内存模型的划分对于Java程序的运行和调优都非常重要。在实际开发中,需要根据具体情况调整JVM内存的配置,以达到更好的性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心向阳光的天域

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值