JVM几个运行时内存区域

<div class="iteye-blog-content-contain" style="font-size: 14px"></div>

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->
 
    1. 程序计数器(线程私有)
     对于JVM来说,每个Java文件都会被编译成.class文件,里面的方法,常量等等,都会被包括在内,但是运行时,如何知道目前线程运行到哪一行命令,就需要程序计数器指出来。在JVM中,多线程是通过线程轮流切换CPU的使用时间来实现,每个线程都会有一小块区域,用来记录当前所执行到的命令的位置,如果不这样的话,那么线程暂停以后,就没法知道目前命令执行到哪一条了。很好理解,这块区域属于线程的私有区域,不允许其他线程访问。
      所需要注意的是,程序计数器只记录Java方法,也就是说,它只记录虚拟机自己的字节指令,对于Native方法,这个计数器的值为空。这块区域是唯一没有规定任何OutOfMemory异常的地方。
 
    2. Java虚拟机栈(线程私有)
      这个栈是真正用来执行Java方法的区域,每当执行到一个Java方法的时候,就会创建一个 栈帧,这个栈帧里面会记录局部变量、操作数栈、动态链接、方法出口和其他附加信息等等,每个方法从开始执行到执行完就是一个出栈到入栈的过程。
     在这个区域,如果线程规定了栈的深度,那么在执行方法时超出了栈的最大深度,那么就会出现StackOutflowError异常,如果虚拟机栈可以扩展,那么在扩展的时候分配不出内存,就会抛出OutOfMemoryError异常。当前大部分的虚拟机都是可以扩展的。
 
    3. Java堆(线程共享)
      对于大多数应用来说,这一块是Java内存分配管理中最大的一块,它是 所有线程共享的,主要用于存储对象实例和数组。这一区域会涉及到Java的内存回收机制Garbage Colleted Heap,这个区域在不同的内存垃圾回收机制下面,会呈现不同的内存空间(不同是指是否规则,回收后是否会进行内存空间整理),当内存空间无法分配的时候抛出OutOfMemoryError
 
    4. 本地方法栈(线程私有)
      与Java虚拟机栈类似,区别在于本地方法栈用于执行 Native方法,Java虚拟机栈却是执行Java字节码的地方。在虚拟机规范中没有规定对此块内存区域应该如何使用,各种虚拟机可以自由实现它。跟Java虚拟机栈一样,会抛出两种异常。
 
    5. 方法区(线程共享)
      各个线程共享,用于储存被加载的类信息、常量、静态变量、即时编译器编译的代码等数据。GC对这块内存的收集是必要而且条件苛刻的,回收主要是针对常量池和对类型的卸载。会出现OutOfMemoryError异常。
 
    6. 运行时常量池(线程共享)
      这块区域是方法去的一部分,.class文件中会有这些信息,用于存放编译时生成的各种字面量和对象的引用,在类加载完成后,放入方法区运行时常量池存放。另外一个特征就是具备动态性,所有常量并不要求在编译期产生,在运行时产生的常量也可以放入该区域,用的最多的就是String.intern()方法 http://bbs.csdn.net/topics/190153906
 
    7. 直接内存
      在Java1.4中加入了NIO(New Input/Output),引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数直接在堆外面分配内存,然后用一个储存在堆里面的DirectByteBuffer对象作为这块内存的引用,能提高IO性能,可能会出现OutOfMemoryError异常。
 
 
 
 
 
 
 
 
 
 
 
 

猜你喜欢

转载自we-are-here.iteye.com/blog/2260783