JVM内存模型-转载

http://my.oschina.net/u/567296/blog/303780

JVM的内部结构如下图:

JVM主要包括两个子系统和两个组件:

1. 两个子系统分别是Class loader子系统和Execution engine(执行引擎) 子系统;

1.1 Class loader子系统的作用:根据给定的全限定名类名(如 java.lang.Object)来装载class文件的内容到 Runtime data area中的method area(方法区域)。Java程序员可以extends java.lang.ClassLoader类来写自己的Class loader。

1.2 Execution engine子系统的作用:执行classes中的指令。任何JVM specification实现(JDK)的核心都是Execution engine,不同的JDK例如Sun 的JDK 和IBM的JDK好坏主要就取决于他们各自实现的Execution engine的好坏。

2. 两个组件分别是Runtime data area (运行时数据区域)组件和Native interface(本地接口)组件。

2.1 Native interface组件:与native libraries交互,是其它编程语言交互的接口。当调用native方法的时候,就进入了一个全新的并且不再受虚拟机限制的世界,所以也很容易出现JVM无法控制的native heap OutOfMemory。

2.2 Runtime Data Area组件:这就是我们常说的JVM的内存了。它主要分为五个部分——

1、Heap (堆):一个Java虚拟实例中只存在一个堆空间,Java堆是被所有线程共享的,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例,绝大部分的对象实例都在这里分配。Java堆内还有更细致的划分:新生代、老年代,再细致一点的:eden、from survivor、to survivor,甚至更细粒度的本地线程分配缓冲(TLAB)等,无论对Java堆如何划分,目的都是为了更好的回收内存,或者更快的分配内存。

Java堆可以处于物理上不连续的内存空间,它逻辑上是连续的即可,就像我们的磁盘空间一样。实现时可以选择实现成固定大小的,也可以是可扩展的,不过当前所有商业的虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中无法分配内存,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

2、Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件内容并把它传输到虚拟机中。叫“方法区”可能认识它的人还不太多,如果叫永久代(Permanent Generation)它的粉丝也许就多了。它还有个别名叫 做Non-Heap(非堆)。

方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。

运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法在申请到内存时会抛出OutOfMemoryError异常。

3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈。栈描述的是Java方法调用的内存模型:每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。

4、Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。

5、Native method stack(本地方法栈):保存native方法进入区域的地址.
以上五部分只有Heap 和Method Area是被所有线程的共享使用的;而Java stack, Program counter 和Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。

此外还有本机直接内存的管理(Direct Memory) -- 直接内存并不是虚拟机运行时数据区的一部分,它根本就是本机内存而不是VM直接管理的区域。

显然本机直接内存的分配不会受到Java堆大小的限制,但是即然是内存那肯定还是要受到本机物理内存(包括SWAP区或者Windows虚拟内存)的限制的,一般服务器管理员配置JVM参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),而导致动态扩展时出现OutOfMemoryError异常。

JVM内存模型实例以及参数对应:

时间: 2024-12-27 00:45:49

JVM内存模型-转载的相关文章

深入理解JVM JVM内存模型

1.JVM内存模型        说起JVM内存模型,都是知道是Java方法区.Java栈.Native方法区.Java堆和程序计数器五部分,不过具体是做什么的,又有什么关系可能大家就不太清楚了,所以话不多说,直接上干货. 首先是JVM内存规范. 编译器和类加载在上篇博客已经讲了,不了解的可去看一下.现在主要就是运行时数据区了.具体请看下图 先给简单介绍一下什么是堆.桟.方法区以及格子 首先就是堆与栈分开设计是为什么呢? 栈存储了处理逻辑.堆存储了具体的数据,这样隔离设计更为清晰堆与栈分离,使得

JVM内存模型小结

JVM运行时的数据区域划分图如下,该图是JVM内存模型最主要的内容. 从图中可以看出来,JVM将内存主要划分为五个部分:程序计数器.Java虚拟机栈.本地方法栈.Java堆和方法区.这些被划分为用途不一的数据区域有着各自的特点,它们都有自己创建和销毁的时间,有的区域随着进程的启动而存在,有的是伴随着用户线程的启动而建立.随着线程的结束而销毁. (一) 程序计数器(Program Counter Register) 1> 内存空间较小; 2> 当前线程所执行的字节码行号指示器: 功能:a.在JV

jvm的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集(转)

深入Java虚拟机:JVM中的Stack和Heap(转自:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap. Stack(栈)是JVM的内存指令区.Stack管理很简单,push

JVM内存模型以及HotSpot的GC策略

概述 想要进一步掌握Java语言,必须要深入了解一下Java程序的运行环境.本文会对JVM的内存模型.Java内存自动管理机制.以及Oracle官方虚拟机HotSpot在GC方面的实现策略进行大概的梳理. 什么是Java的内存模型? 众所周知,Java程序是运行在JVM上面的,但是不具体指定是哪一款JVM,只要是符合一定的规范的JVM,都可以正确的运行Java字节码.该规范由Oracle官方提供,旨在描述一个抽象的JVM,它包含很多部分,包括class文件结构.运行时内存状态.指令集等. 而上述

jvm内存模型及分配

1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域.(3)JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行.JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行. 2.jdk.jre.jvm是什么关系?(1)JRE(Java

JVM内存模型理解

Java虚拟机(Java VirtualMachine 简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一. JVM内存模型 1.方法区和堆是所有线程共享的数据区 1)堆:存放对象的实例 2)方法区:存放已被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码 3)运行时常量池:是方法区的一部分,存放Class的版本.字段.方法.接口等描述信息,字符串池就是这个!!! 2.程序计数器.虚拟机栈.本地方法栈是线程隔离的数据区 4)程序

JVM内存模型及垃圾回收机制

JVM内存模型1.栈Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程.存储局部变量.引用.方法.返回值等.StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的.2.堆 Java中堆是由所有的线程共享的一块内存区域,堆用来保存各种JAVA对象,比如数组,线程对象等. 2.1堆的分代JVM堆一般分为三个部分:Young:年轻代Young区被划分为三部分,Eden区和两个大小严格相同的Su

JVM内存模型及String对象内存分配

昨天看了一篇关于<Java后端程序员1年工作经验总结>的文章,其中有一段关于String和StringBuffer的描述,对于执行结果仍然把握不准,趁此机会也总结了下JVM内存模型. 1.JVM运行时数据区域 关于JVM内存模型之前也了解过一些,也是看过就忘,好记性比如烂笔头,记下来吧.参考此文章http://chenzhou123520.iteye.com/blog/1585224 图1 JVM运行时数据区域 (1).程序计数器(Program Counter Register): 程序计数

JVM内存模型,垃圾回收算法

JVM内存模型总体架构图 程序计数器多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源.因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令.线程私有的内存区域.如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空.虚拟机栈线程私有的,与线程在同一时间创建.管理JAVA方法执行的内存模型.每个方法执行时都会创建一个桢栈来存储方法的的变量表.操作数栈.动态链接方法.返回值.返回地址等信息.