徐无忌深入JVM虚拟机笔记:JDK8后虚拟机内存包含哪几部分?做了哪些调整与改进?

徐无忌深入JVM虚拟机笔记:JDK8后虚拟机内存包含哪几部分?做了哪些调整与改进?

完成:第一遍

1.JDK8之前的架构是什么样子的?

JDK8之前分为:


程序计数器
本地方法栈
方法区即永久代

栈、程序计数器和本地方法栈是线程私有的
堆和永久代是线程共享的

2.堆的作用是什么?

堆是JVM内存管理的最大的一块区域,主要目的是存放对象的实例

所有新创建的对象实例和数组都会在对上为其分配内存空间

线程共享

是垃圾收集器的主要管理区域,堆内存中可以存在物理上不连续的空间,只要逻辑上是连续的即可

如果在堆中没有内存完成实例分配,将抛出OutOfMemoryError

3.栈的作用是什么?

Java栈也称作虚拟机栈(Java Vitual Machine Stack),是线程私有的

Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法

在栈帧中包括:
局部变量表(Local Variables)
操作数栈(Operand Stack)
动态链接(调用另外一个方法)
方法返回地址(Return Address)和一些额外的附加信息

4.本地方法栈的作用是什么?

专门为Native本地方法来实现的,线程私有

Java语言不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言(如C和C++)来实现对底层的访问

简而言之,一个本地方法就是一个Java调用非Java代码的接口

5.程序计数器的作用是什么?

它存储着当前线程所执行的字节码的行号

字节码解释器工作时,就是通过改变这个计数器的值,来让线程知道接下来需要执行哪条字节码指令

线程私有,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,每个线程之间的计数器互不影响

6.方法区即永久代的作用是什么?

方法区在JVM中也是一个非常重要的区域,它是被线程共享的区域

在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等

是一片连续的内存空间,通过-XX:MaxPermSize可以设定永久代最大可分配空间

7.方法区即永久代的缺点是什么?

为方法区分配多大的空间很难确定,因为它的大小依赖于很多因素,比如JVM加载的class总数,常量池的大小,方法的大小等

随着动态加载类的情况越来越多,这块内存变得越来越不可控

如果设置小了,当JVM加载的类信息容量超过了这个值,系统运行过程中就容易出现内存溢出OOM:PermGen的错误,设置大了又浪费内存

8.JDK8之后的JVM主要的变化是什么?

JDK8之后的JVM主要的变化为:
移除了永久代(PermGen)
替换为元空间(Metaspace)

永久代中的类信息转移到了本地内存中的元空间中;
永久代中的 字符串常量池(interned Strings) 和静态变量( class static variables) 转移到了堆中;

永久代参数 (PermSize MaxPermSize) -> 元空间参数(MetaspaceSize MaxMetaspaceSize)

元空间并不放在JVM的内存空间中
而是放置在JVM内存空间之外的直接内存中,
并且JDK8中对于方法区的修改参数PermSize和MaxPermSize已经失效

9.什么是直接内存?

直接内存指这些内存直接受操作系统管理,而不是虚拟机

这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响

使用未公开的Unsafe和NIO包下ByteBuffer来进行分配

10.元空间中放了哪些东西?

JDK8将类的相关信息放到元空间中,将常量池和静态变量放到Java堆内

在这种架构下,元空间就突破了原来-XX:MaxPermSize的限制,现在可以使用更多的本地内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值