文章插图
推荐博客(如果英语好的话,也可以去官网查看):
字节码指令大全
然后,再结合我们上面的Java虚拟机栈这块知识,就能轻松阅读了 。
栈帧的创建是需要耗费资源的,尤其是对于 Java 中常见的 getter、setter 方法来说,这些代码通常只有一行,每次都创建栈帧的话就太浪费了 。
另外,Java 虚拟机栈对代码的执行,采用的是字节码解释的方式,考虑到下面这段代码,变量 a 声明之后,就再也不被使用,要是按照字节码指令解释执行的话,就要做很多无用功 。
另外,我们了解到垃圾回收器回收的目标区域主要是堆,堆上创建的对象越多,GC 的压力就越大 。要是能把一些变量,直接在栈上分配,那 GC 的压力就会小一些 。
3.程序计数器既然是线程,就要接受操作系统的调度,但总有时候,某些线程是获取不到 CPU 时间片的,那么当这个线程恢复执行的时候,它是如何确保找到切换之前执行的位置呢?这就是程序计数器的功能 。
和 Java 虚拟机栈一样,它也是线程私有的 。程序计数器只需要记录一个执行位置就可以,所以不需要太大的空间 。事实上,程序计数器是 JVM 规范中唯一没有规定 OutOfMemoryError 情况的区域 。
4.本地方法栈与 Java 虚拟机栈类似,本地方法栈,是针对 native 方法的 。我们常用的 HotSpot,将 Java 虚拟机栈和本地方法栈合二为一,其实就是一个本地方法栈,大家注意规范里的这些差别就可以了 。
5.元空间元空间是一个容易引起混淆的区域,原因就在于它经历了多次迭代才成为现在的模样 。关于这部分区域,我们来讲解两个面试题,大家就明白了 。
- 元空间是在堆上吗?
- 字符串常量池在那个区域中?
在 JDK 1.8 之前,是没有元空间这个概念的,当时的方法区是放在一个叫作永久代的空间中 。
而在 JDK 1.7 之前,字符串常量池也放在这个叫作永久带的空间中 。但在 JDK 1.7 版本,已经将字符串常量池从永久带移动到了堆上 。
所以,从 1.7 版本开始,字符串常量池就一直存在于堆上 。
- 为什么使用元空间替换永久代?
6.直接内存直接内存,指的是使用了 Java 的直接内存 API,进行操作的内存 。这部分内存可以受到 JVM 的管控,比如 ByteBuffer 类所申请的内存,就可以使用具体的参数进行控制 。
需要注意的是直接内存和本地内存不是一个概念 。
- 直接内存比较专一,有具体的 API(这里指的是ByteBuffer),也可以使用 -XX:MaxDirectMemorySize 参数控制它的大小;
- 本地内存是一个统称,比如使用 native 函数操作的内存就是本地内存,本地内存的使用 JVM 是限制不住的,使用的时候一定要小心 。
把不再使用的对象及时地从堆空间清理出去,是避免 OOM 有效的方法 。那 JVM 是如何判断哪些对象应该被清理,哪些对象需要被继续使用呢?
这里首先强调一个概念,这对理解垃圾回收的过程非常有帮助,面试时也能很好地展示自己 。
垃圾回收,并不是找到不再使用的对象,然后将这些对象清除掉 。它的过程正好相反,JVM 会找到正在使用的对象,对这些使用的对象进行标记和追溯,然后一股脑地把剩下的对象判定为垃圾,进行清理 。
了解了这个概念,我们就可以看下一些基本的衍生分析:
- GC 的速度,和堆内存活对象的多少有关,与堆内所有对象的数量无关;
- GC 的速度与堆的大小无关,32GB 的堆和 4GB 的堆,只要存活对象是一样的,垃圾回收速度也会差不多;
推荐阅读
- 大一新生入学必备清单 上大学要带什么东西
- |混职场必备的五句防身“黑话”,你真正懂得几句,不来了解一下?
- 工作室|梦幻西游:抢资材必备的姿势,新旧两版来回切换,资材量能翻倍
- 鸡胸肉|减脂必备主食:瘦身菜团子,口感鲜香,饱腹感强,好吃不长胖
- 初一女生开学必备物品清单 开学必备物品清单女生
- 中学|县城中学招语文老师,“一个必备条件”让人意外,普通人达不到
- 三角形斜边长度怎么算必备计算公式 直角三角形斜边怎么算
- 韩国旅游必备地图APP 综合评测 韩国旅游地图
- 家电选购全攻略 家电选购必备指南
- 森林燃气灶必备品牌荣誉
