JDK8的JVM内存结构,元空间替代永久代成为方法区及常量池的变化
JVM的知识这里总结的很详细:https://github.com/doocs/jvm/blob/master/README.md,因此在本博客也不会再对其中的东西重复总结了。
现在很多文章关于JVM内存结构的说法模糊不清,这里记录一下以前的一些比较模糊的JVM相关概念的重新认识。都是经过多处考证对比的。
MetaSpace代替Perm Gen
即元空间代替了永久代,所以JVM关于永久代的参数也都作废了,取而代之的是关于MetaSpace空间的参数。而且Mete Space是属于直接内存。示意图:
(图片来源于网络)
为什么要在直接内存里拿出来一块内存作为元空间取代永久代呢?主要的说法有以下几个:
(1)类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
(2)永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
即方便分配管理,因为直接内存空间比较充足;便于回收,因为永久代本来回收垃圾的事件发生概率很低,直接从JVM中拿出可以提高回收效率。
方法区与永久代的关系
很多文章里喜欢把方法区等同与永久代,永久代既然没了,方法区也就没了。但我认为方法区只是一种逻辑上的概念,永久代指物理上的堆内存的一块空间,这块实际的空间完成了方法区存储字节码、静态变量、常量的功能等等。既然如此,现在元空间也可以认为是新的方法区的实现了。
常量池随永久代的变化
常量池主要可以分为以下几种:
(1)静态常量池:即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串/数字这些字面量,还包含类、方法的信息,占用class文件绝大部分空间。这种常量池主要用于存放两大类常量:字面量和符号引用量,字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等;符号引用则属于编译原理 方面的概念,包括了如下三种类型的常量:类和接口的全限定名、字段名称描述符、方法名称描述符。
类的加载过程中的链接部分的解析步骤就是把符号引用替换为直接引用,即把那些描述符(名字)替换为能直接定位到字段、方法的引用或句柄(地址)。
(2)运行时常量池:虚拟机会将各个class文件中的常量池载入到运行时常量池中,即编译期间生成的字面量、符号引用,总之就是装载class文件。
(3)字符串常量池 :字符串常量池可以理解为运行时常量池分出来的部分。加载时,对于class的静态常量池,如果字符串会被装到字符串常量池中。
(4)整型常量池:Integer,类似字符串常量池,可以理解为运行时常量池分出来的。加载时,对于class的静态常量池装的东西,如果是整型会被装到整型常量池中。
类似的还有Character、Long等等常量池(基本数据类型没有哦)。。。
在永久代移除后,字符串常量池也不再放在永久代了,但是也没有放到新的方法区---元空间里,而是留在了堆里(为了方便回收?)。运行时常量池当然是随着搬家到了元空间里,毕竟它是装静态变量、字节码等信息的,有它的地方才称得上方法区。
JDK8的JVM内存结构,元空间替代永久代成为方法区及常量池的变化的更多相关文章
- 面试官,Java8 JVM内存结构变了,永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
- JAVA8 JVM内存结构变了,永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
- 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...
- JVM内存模型——堆(heap)、栈(stack)和方法区(method)
JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:堆内存用于存放由new创建的对象和数组.堆是JVM管理的内存中最大的一块,堆被所有线程共享,目的 ...
- [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...
- JVM 内存初学 堆(heap)、栈(stack)和方法区(method)
这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...
- JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )(转载)
想想面试的时候很多会问jvm这方面的问题虽然还是菜鸟不太能用到现在但是还是了解一下, 找资料的时候看见个大佬写的很好转载到这方便以后自己复习和给大佬做宣传 以下为大佬的博客原文: 这两天看了一下深入浅 ...
- jdk8永久代从方法区移除的验证
/*** 测试使用jdk8中是否仍然可以使用永久代* jvm options * -Xms20m -Xmx20m -Xmn10m -XX:PermSize=10m -XX:MaxPermSize=10 ...
- Eclipse中的快捷键快速生成常用代码(例如无参、带参构造,set、get方法),以及Java中重要的内存分析(栈、堆、方法区、常量池)
(一)Eclipse中的快捷键: ctrl+shift+f自动整理选择的java代码 alt+/ 生成无参构造器或者提升信息 alt+shift+s+o 生成带参构造 ctrl+shift+o快速导 ...
随机推荐
- 带新手玩转MVC——不讲道理就是干(下)
带新手玩转MVC——不讲道理就是干(下) 前言:废话不多说,直接开干 完整案例演示 案例代码 LoginServlet package servlet; import domain.User; imp ...
- IO流3
public class Test1 { public static void main(String[] args) throws Exception { //第二个参数,表示是否向末尾追加,tru ...
- MD、SHA、MAC消息摘要算法实现与应用
1.消息摘要概述 消息摘要(Message Digest)又称为数字摘要(Digital Digest).它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生 ...
- 【MySQL】java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\xB3' for column
问题原因: 输入内容包含特殊字符,MySQL 中的列不支持. 解决方法 多数是修改 MySQL 的数据库和表结构,CHARSET 改为 utf8mb4,但本人测试还是不能传入 emoji. 后来在代码 ...
- 模拟器无Back、Menu等键
问题如图所示: 解决方法: 1. 打开Android Virtual Device (AVD) Manager --> 选择模拟器,并点击edit --> 勾选KeyBoard中的选项,并 ...
- 【Algorithm】插入排序法
通常人们整理桥牌的方法是一张一张的来,将每一张插入到其他已经有序的牌中的适当位置. • 思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的序列的合适位置,直到全部插入排序完为止. Jav ...
- React Hooks 深入系列 —— 设计模式
本文是 React Hooks 深入系列的后续.此篇详细介绍了 Hooks 相对 class 的优势所在, 并介绍了相关 api 的设计思想, 同时对 Hooks 如何对齐 class 的生命周期钩子 ...
- js实现3D切换效果
今天分享一个3d翻转动画效果,js+css3+h5实现,没有框架. 先看下html部分: <div class="box"> <ul> <li> ...
- codeforces 322 A Ciel and Dancing
题目链接 题意: 有n个男孩和m个女孩,他们要结对跳舞,每对要有一个女孩和一个男孩,而且其中一个要求之前没有和其他人结对,求出最大可以结多少对. 如图,一条线代表一对,只有这样三种情况. #inclu ...
- 标签助手(TagHelper)
1.什么是标签助手 Tag Helper 标签助手是服务端代码能够参与在 Razor 文件中创建和呈现HTML元素.例如,内置的 ImageTagHelper 可以将版本号追加到图像名称.无论何时更改 ...