java虚拟机的内存区域划分

标签: java 虚拟机 内存 | 发表时间:2012-07-23 13:28 | 作者:mhmyqn
出处:http://blog.csdn.net

         java虚拟机在执行java程序的过程中会把它所管理的内存划分成很多个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。Java虚拟机规范中把java虚拟机所管理的内存划分为以下几个区域。

一、程序计数器(Program Counter Register)

         程序计数器是一块较小的内存空间,它的作用是当前所执行的字节码的行号指示器。它是线程私有的,即各个线程都有独立的程序计数器。

         如果线程正在 执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是native方法,则这个计数器是空(undefined)。

         此内存区域是唯一的一个不会抛出OutOfMemoryError异常的区域。

二、java虚拟机栈(Java Virtual Machine Stacks)

         我们可能经常听到说java内存分为堆内存和栈内存,其实这个说法中的栈内存是指java虚拟机栈中的局部变量表部分。

         Java虚拟机栈描述的是java方法执行的内存模型:每个方法被执行时都会同时创建一个栈帧(Stack Frame),用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。Java虚拟机栈也是线程私有的,生命周期也线程相同。

         局部变量表存放的类型包括以下三种:

1、  编译期可知的基本数据类型:boolean、byte、char、short、int、float、long、double共8 种类型;

2、  对象引用:即reference类型,它存放的是一个指向堆中对象起始地址的引用指针,或一个代表对象的句柄或者其他与此对象相关的位置,根据虚拟机的不同实现而不同;

3、  returnAddress类型:存放指向一条字节码指令的地址;

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量表空间是完全确定了的,方法在运行期间不会改变局部变量表的大小。

Java虚拟机栈会抛出两种异常:

1、             OutOfMemoryError异常:如果虚拟本可以动态扩展,当扩展时无法申请到足够的内存时抛出;

2、             StackOverflowError异常:如果线程请求的栈深度大于虚拟机所允许的深度时抛出;

三、本地方法栈(Native Method Stacks)

         本地方法栈与虚拟机栈的作用相似,它是为虚拟机在执行native方法时服务,而虚拟机栈是为虚拟机执行java方法服务。此内存区域也会抛出OutOfMemoryError异常和StackOverflowError异常。

四、java堆(Java Heap)

         java堆是用于存放对象实例和数组。它是java虚拟机管理的内存中最大的一块,被所有线程共享,在虚拟机启动时创建,也是垃圾收集器管理的要区域,几乎所有的对象实例都在这里分配内存。

         如果垃圾收集器采用的是分代收集它还,它还可以细分为新生代和老年代,再细致一点的有Enden空间、From Survivor空间、To Survivor空间等。

         java堆可以处理物理上不连续的内存空间中,只要逻辑上连续即可。在实现时既可以实现丰固定大小的,也可以是可扩展的。如果是可扩展的,可以通过-Xms和-Xmx来指定最小和最大值,如果-Xms和-Xmx的值相等,则相当于不可扩展了。如果堆中没有内存可完成实例分配,此内存区域会抛出OutOfMemoryError异常。

         五、方法区

         方法区用于存放已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。它是堆的一个逻辑部分,是各个线程共享的内存区域。如果是sun的HotSpot虚拟机,它也叫做永久代(Permanent Generation),如果方法区无法满足内存分配需求时,会抛出OutOfMemoryError异常。

         方法区中的运行时常量池(RuntimeConstant Pool),用于存放编译期生成的各种字面量和符号引用,它在类加载后存放到运行时常量池中。

         运行时常量池具有动态性,即常量不一定只在编译期产生,在运行期间也可能将新的常量存入池中,比如String类的intern()方法。

         六、直接内存(DirectMemory)

         它不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。比如在JDK1.4中新加入的NIO类,有一种基于通道与缓冲区的I/O方式,它可以使用native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。所以直接内存不会受到java堆大小的限制,但会受到本机总内存的大小及处理器寻址空间的限制。它也会抛出OutOfMemoryError异常。

作者:mhmyqn 发表于2012-7-23 13:28:18 原文链接
阅读:0 评论:0 查看评论

相关 [java 虚拟机 内存] 推荐:

Java虚拟机学习 - 内存调优

- - CSDN博客推荐文章
JVM调优主要是针对内存管理方面的调优,包括控制各个代的大小,GC策略. 由于GC开始垃圾回收时会挂起应用线程,严重影响了性能,调优的目是为了尽量降低GC所导致的应用线程暂停时间、 减少Full GC次数. 最关键参数:-Xms、 -Xmx 、-Xmn 、-XX:SurvivorRatio、-XX:MaxTenuringThreshold、-XX:PermSize、-XX:MaxPermSize.

java虚拟机的内存区域划分

- - CSDN博客推荐文章
         java虚拟机在执行java程序的过程中会把它所管理的内存划分成很多个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁. Java虚拟机规范中把java虚拟机所管理的内存划分为以下几个区域.

深入Java虚拟机之内存优化

- - ITeye博客
前面一篇文章介绍了Java虚拟机的体系结构和内存模型,既然提到内存,就不得不说到内存泄露. 众所周知,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题就是内存泄露难以解决,尽管Java的JVM有一套自己的垃圾回收机制来回收内存,在许多情况下并不需要java程序开发人员操太多的心,但也是存在泄露问题的,只是比C++小一点.

Java虚拟机(JVM)中的内存设置详解及优化

- - Java - 编程语言 - ITeye博客
JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制. 32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制. 我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m.

探秘Java虚拟机——内存管理与垃圾回收

- - 编程语言 - ITeye博客
探秘Java虚拟机——内存管理与垃圾回收. 本文主要是基于Sun JDK 1.6 Garbage Collector(作者:毕玄)的整理与总结,原文请读者在网上搜索. 1、Java虚拟机运行时的数据区. 2、常用的内存区域调节参数. -Xms:初始堆大小,默认为物理内存的1/64(<1GB);默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.

Java 虚拟机 7:内存分配原则

- - ImportNew
对象的内存分配,往大的方向上讲,就是在堆上分配,少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节决定于当前使用的是哪种垃圾收集器组合,当然还有虚拟机中与内存相关的参数. 垃圾收集器组合一般就是Serial+Serial Old和Parallel+Serial Old,前者是Client模式下的默认垃圾收集器组合,后者是Server模式下的默认垃圾收集器组合,文章使用对比学习法对比Client模式下和Server模式下同一条对象分配原则有什么区别.

Java虚拟机家族考

- ReadReply - 博客园新闻频道
  说起Java虚拟机,许多Java程序员都会潜意识地把它与Sun[1] HotSpot虚拟机等同看待,也许还有一些程序员会注意到BEA JRockit和IBM J9,但大多数人对JVM的认识都仅限于此了.   从1996年初Sun发布的JDK 1.0中所包含的Sun Classic VM算起,Java虚拟机已经发展了15个年头,沧海桑田一瞬间,15年转眼而过,这期间曾经涌现、湮灭过许多或经典或优秀或有特色的虚拟机实现,在《Java虚拟机专栏》的第1篇中,我们先暂且把代码与技术放下,一起来回顾一下Java虚拟机家族的发展轨迹和历史变迁.

文章: Java虚拟机家族考

- Haides - InfoQ中文站
说起Java虚拟机,许多Java程序员都会潜意识地把它与Sun HotSpot虚拟机等同看待,也许还有一些程序员会注意到BEA JRockit和IBM J9,但大多数人对JVM的认识都仅限于此了. 从1996年初Sun发布的JDK 1.0中所包含的Sun Classic VM算起,Java虚拟机已经发展了15个年头,沧海桑田一瞬间,15年转眼而过,这期间曾经涌现、湮灭过许多或经典或优秀或有特色的虚拟机实现,在《Java虚拟机专栏》的第1篇中,我们先暂且把代码与技术放下,一起来回顾一下Java虚拟机家族的发展轨迹和历史变迁.

历史篇:Java虚拟机家族考

- Guancheng(冠诚) - FenixSoft 3.0
  声明:本文为笔者原创,但首发于InfoQ中文站,详见文末声明.   说起Java虚拟机,许多Java程序员都会潜意识地把它与Sun[注1] HotSpot虚拟机等同看待,也许还有一些程序员会注意到BEA JRockit和IBM J9,但大多数人对JVM的认识都仅限于此了.   从1996年初Sun发布的JDK 1.0中所包含的Sun Classic VM算起,Java虚拟机已经发展了15个年头,沧海桑田一瞬间,15年转眼而过,这期间曾经涌现、湮灭过许多或经典或优秀或有特色的虚拟机实现,在《Java虚拟机专栏》的第1篇中,我们先暂且把代码与技术放下,一起来回顾一下Java虚拟机家族的发展轨迹和历史变迁.