JVM内存管理-内存区域

来源:互联网 发布:免费域名注册申请 编辑:程序博客网 时间:2024/06/05 06:35

一、JVM理解

 JVM 即为java虚拟机,不是所有能运行java语言的虚拟机都是java虚拟机,必须通过 Java TCK(Technology Compatibility Kit)的兼容性测试的Java语言虚拟机才能称为“Java™ 虚拟机。然而jvm是一种概念模型(公有设计,私有实现),厂商可以根据自己的实现去实现jvm的要求,例如,jvms规定java堆区一定要实现自动回收的内存管理,但是没有规定怎么实现,各个厂商可以根据自己的算法去实现回收管理。目前三大商用的JVM实现有Oracle HotSpot 、 Oracle JRockit VM、IBM J9 VM,我们官方下载的,就是我们使用的最多的就是hotSpot这个实现。

二、运行时的数据区

主要分为4个区域:程序计数器、Java 堆、Java 虚拟机栈(本地方法栈)、方法区



程序计数器:一块较小的的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器,如果线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是 Native 方法,这个计数器值则为空。此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError情况的区域。

虚拟机栈和本地方法栈:线程私有、后进先出(LIFO)栈、存储栈帧,支撑 Java 方法的调用、执行和退出、会出现OutOfMemoryError 异常和 StackOverflowError 异常

栈帧:Java 虚拟机栈中存储的内容,它被用于存储数据和部分过程结果的数据结构,同时也被用来处理动态链接、方法返回值和异常分派,一个完整的栈帧包含:局部变量表、操作数栈、动态连接信息、方法正常完成和异常完成信息。

一个方法做加法运算例子:

int a = 100;int b = 200;int c = 300;return (a+b)*c

程序运行的图为


java堆:全局共享,存放java的实例对象,JVMS 明确要求该区域需要实现自动内存管理,即常说的 GC,但并不限制采用哪种算法和技术去实现,做为hotspot的实现,堆与栈的关系是如下图:


方法区:全局共享,作用是存储 Java 类的结构信息,JVMS 不要求该区域实现自动内存管理,但是商用 Java 虚拟机都能够自动管理该区域的内存。运行时常量区,是方法区的一部分,作用是存储JAVA类文件常量池中的符号信息

永久代与方法区:在 JDK 1.2 ~ JDK 6,HotSpot 使用永久代实现方法区,在JDK7开始,hotSpot移除了永久代,

                            * 符号表被移到 Native Heap 中

                            * 字符串常量和类的静态引用被移到 Java Heap 中

那么导致JDK6 和 JDK7运行以下代码产生影响:

String str1 = new StringBuilder("哈哈).append("呵呵").toString();System.out.println(str1.intern() == str1);

在JDK6中,返回的是false,JDK7中返回true,主要是常量池存放的地方不一样,java7前,常量池是在永久代的内存中的,而对象在堆中的地址,到了java7以后,常量池也存放在堆中,因此当第一次运行的时候,常量池没有该值,就会去内存中拿(堆),所以其实地址是一样的。




0 0
原创粉丝点击