JVM学习-基础篇-堆方法区
堆一般 Java 程序中堆内存是空间最大的一块内存区域。创建出来的对象都存在于堆上。栈上的局部变量表中可以存放堆上对象的引用。静态变量也可以存放堆对象的引用通过静态变量就可以实现对象在线程之间共享。public class Test { public static void main(String[] args) { Student s1 new Student(); s1.name 张三; s1.age 18; s1.id 1; s1.printTotalScore(); s1.printAverageScore(); Student s2 new Student(); s2.name 李四; s2.age 19; s2.id 2; s2.printTotalScore(); s2.printAverageScore(); } }这段代码中通过 new 关键字创建了两个 Student 类的对象这两个对象会被存放在堆上。在栈上通过 s1和 s2 两个局部变量保存堆上两个对象的地址从而实现了引用关系的建立。堆内存的溢出堆内存大小是有上限的当对象一直向堆中放入对象达到上限之后就会抛出OutOfMemory错误。三个重要的值堆空间有三个需要关注的值used、total、max。used指的是当前已使用的堆内存total是java虚拟机已经分配的可用堆内存max是java虚拟机可以分配的最大堆内存。设置堆的大小要修改堆的大小可以使用虚拟机参数 –Xmxmax最大值和-Xms (初始的total)。语法-Xmx值 -Xms值单位字节默认必须是 1024 的倍数、k或者K(KB)、m或者M(MB)、g或者G(GB)限制Xmx必须大于 2 MBXms必须大于1MB-Xms6291456 -Xms6144k -Xms6m -Xmx83886080 -Xmx81920k -Xmx80m方法区方法区是存放基础信息的位置线程共享主要包含1、 类的元信息保存了所有类的基本信息2、 运行时常量池保存了字节码文件中的常量池内容- 编译期生成的字面量如字符串字面量、final常量- 符号引用3、 静态变量4、 即时编译器JIT编译后的代码类的元信息方法区是用来存储每个类的基本信息元信息一般称之为 InstanceKlass对象。在类的加载阶段完成。其中就包含了类的字段、方法等字节码文件中的内容同时还保存了运行过程中需要使用的虚方法表实现多态的基础等信息。运行时常量池常量池中存放的是字节码中的常量池内容。字节码文件中通过编号查表的方式找到常量这种常量池称为静态常量池。当常量池加载到内存中之后可以通过内存地址快速的定位到常量池中的内容这种常量池称为运行时常量池。字符串常量池方法区中除了类的元信息、运行时常量池之外还有一种区域叫字符串常量池String Table字符串常量池存储在代码中定义的常量字符串内容。比如“123”这个123就会被放入字符串常量池。方法区的实现- JDK 7将方法区存放在堆区域的永久代空间堆的大小由虚拟机参数 -XX:MaxPermSize 值来控制。- JDK 8将方法区存放在元空间中元空间位于操作系统维护的直接内存中默认情况下只要不超过操作系统承受的上限可以一直分配。可以使用 -XX:MaxMetaspaceSize 值将元空间最大大小进行限制。在 JDK 7 及之前的版本中静态变量是存储在方法区永久代的而从 JDK 8 开始随着永久代的移除静态变量被存储在了堆区并且位于 Class 对象内部。