分享

元空间介绍

 __安如少年 2020-12-09

关于元空间,我们还是以一个非常高频的面试题开始——

为什么有 Metaspace 区域?它有什么问题?

说到这里,你应该回想一下类与对象的区别。

▲ 对象是一个活生生的个体,可以参与到程序的运行中

▲ 类更像是一个模版,定义了一系列属性和操作

那么你可以设想一下:我们生成的 A.class,是放在 JVM 的哪个区域的?

想要问答这个问题,就不得不提下 Java 的历史。

在 Java 8 之前,这些类的信息是放在一个叫 Perm 区的内存里面的。更早版本,甚至 String.intern 相关的运行时常量池也放在这里。

这个区域有大小限制,很容易造成 JVM 内存溢出,从而造成 JVM 崩溃。

Perm 区在 Java 8 中已经被彻底废除,取而代之的是 Metaspace。原来的 Perm 区是在堆上的,现在的元空间是在非堆上的,这是背景。

关于它们的对比,可以看下这张图。

元空间的好处也是它的坏处。

使用非堆可以使用操作系统的内存,JVM 不会再出现方法区的内存溢出;但是,无限制的使用会造成操作系统的死亡。

所以,一般也会使用参数 -XX:MaxMetaspaceSize 来控制大小。

方法区,作为一个概念,依然存在。它的物理存储的容器,就是 Metaspace。

现在你只需要了解到,这个区域存储的内容包括:类的信息、常量池、方法数据、方法代码。

我们常说的字符串常量,存放在哪呢?

由于常量池,在 Java 7 之后,放到了堆中,我们创建的字符串,将会在堆上分配。

堆、非堆、本地内存,有什么关系?

关于它们的关系,我们可以看一张图。

在我的感觉里

▲ 堆是软绵绵的,松散而有弹性

▲ 非堆是冰冷生硬的,内存非常紧凑

大家都知道,JVM 在运行时,会从操作系统申请大块的堆内内存,进行数据的存储。

但是,堆外内存也就是申请后操作系统剩余的内存,也会有部分受到 JVM 的控制。比较典型的就是一些 native 关键词修饰的方法,以及对内存的申请和处理。

在 Linux 机器上,使用 top 或者 ps 命令,在大多数情况下,能够看到 RSS 段(实际的内存占用),是大于给 JVM 分配的堆内存的。

如果你申请了一台系统内存为 2GB 的主机,可能 JVM 能用的就只有 1GB,这便是一个限制。

JVM 的运行时区域是栈,而存储区域是堆。很多变量,其实在编译期就已经固定了。.class 文件的字节码,由于助记符的作用,理解起来并不是那么吃力。

JVM 的运行时特性,以及字节码,是比较偏底层的知识。

本文属于初步介绍,有些部分并未深入讲解。希望你应该能够在脑海里建立一个 Java 程序怎么运行的概念。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多