http://blog.csdn.net/sczyh22/article/details/46652901<br>
Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域。

有的人把JVM管理的内存简单地分为堆内存和栈内存,这样分未免有些太肤浅了。
Java的内存区域主要分为五部分:

程序计数器(PC)
Java 虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack)
Java 堆内存(Java Heap)
方法区(Method Area)
Java内存区域
(图转自网络)

下面我们来解析这几个区域。

1、程序计数器

相信学过计算机组成原理的人都知道,CPU内部的寄存器中就包含一个程序计数器(x86下为eip寄存器,ARM下为R15寄存器),存放程序执行的下一条指令地址。在程序开始执行前,将程序指令序列的起始地址,即程序的第一条指令所在的内存单元地址送入PC,CPU按照PC的地址从内存中读取第一条指令。每一条指令执行时,CPU会自动修改PC的量至下一条指令的地址,指令之间的跳转离不开PC。JVM内存中的程序计数器也是这样的作用,它储存JVM当前执行bytecode的地址。

Java虚拟机允许多个线程同时执行指令。如果有多个线程正在执行指令,那么每个线程都会有一个程序计数器,它是线程私有的。在任意时刻,一个线程只允许执行一个方法的代码。每当执行到一条Java方法的指令时,程序计数器保存当前执行字节码的地址;若执行的为native方法,则PC的值为undefined。

2、Java 虚拟机栈

Java虚拟机栈也是线程私有的,每一条线程都拥有自己私有的Java 虚拟机栈,它与线程同时创建。它描述了Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至完成的过程,都对应一个栈帧从入栈到出栈的过程。关于栈帧详细的内容在后边复习虚拟机字节码执行引擎的时候再说吧。
Java 虚拟机栈在方法调用和返回中也扮演了很重要的角色。因为除了栈帧的入栈和出栈之外,Java虚拟机栈不会再受其它因素的影响,因此栈帧可在系统的堆上分配内存(注意,是系统的Heap而不是Java Heap)。Java虚拟机栈所使用的内存不需要保证是连续的。

3、本地方法栈

本地方法栈和Java虚拟机栈的作用相似,Java虚拟机栈执行的是字节码,而本地方法栈执行的是native方法。本地方法栈使用传统的栈(C Stack)来支持native方法。在HotSpot JVM中Java虚拟机栈和本地方法栈合二为一。

4、Java 堆

在JVM中,Java 堆是可供各线程共享的运行时内存区域,是Java 虚拟机所管理的内存区域中最大的一块。此区域非常重要,几乎所有的对象实例和数组实例都要在Java堆上分配,但随着JIT编译器及逃逸分析技术的发展,也可能会被优化为栈上分配,高大上。。。)。同时,Java 堆也是发生GC收集的主要区域。
从内存回收的角度来看,它可以分为新生代和老年代,再细分可以分为Eden Space,From Survivor Space,To Survivor Space区域。Java堆的容量可以是固定的,也可以随着需要来扩展,并且在用不到的时候自动收缩。

5、方法区

方法区是线程共享的,它储存了每一个类的结构信息,比如运行时常量池(runtime constant pool)、字段和方法数据、构造函数和普通方法的字节码内容,还包括一些初始化的时候用到的特殊方法。方法区是堆的逻辑部分。
在JDK1.7及以前的HotSpot JVM中,方法区位于永久代(Permanent Generation,PermGen)中。由于永久代内可能会发生内存泄露或溢出等问题而导致的java.lang.OutOfMemoryError: PermGen ,JEP小组从JDK1.7开始就筹划移除永久代(JEP 122: Remove the Permanent Generation),并且在JDK 1.7中把字符串常量,符号引用等移出了永久代。到了Java 8,永久代被彻底地移出了JVM,取而代之的是元空间(Metaspace):

In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.
所以从Java 8开始,方法区被移至Metaspace 内。有关Metaspace的相关总结,见下一篇文章。

6、运行时常量池

运行时常量池是class文件中每一个类或接口的常量池表的运行时表示形式,是方法区的一部分。它包括了若干种不同的常量。常量池表存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。运行时常量池具有动态性,运行期间也可以将新的量放到运行时常量池中,典型的应用是String类的intern方法:

public native String intern()
1
JDK 7开始,字符串常量和符号引用等就被移出永久代:

符号引用迁移至系统堆内存(Native Heap)
字符串字面量迁移至Java堆(Java Heap)
下一篇文章我将会总结Java 8中的Metaspace相关知识。

深入探究JVM(1) - Java的内存区域解析的更多相关文章

  1. 重读《深入理解Java虚拟机》一、Java虚拟机内存区域的划分

    一.Java虚拟机内存区域如何划分 1.Java虚拟机内存区域的划分 区域名称 作用(用途) 类型 特点 虚拟机规定异常情况 内存分配与回收 其他说明 1 程序计数器 指示当前正在执行的字节码指令地址 ...

  2. java的内存区域

    java的内存区域分为程序计数器.java虚拟机栈.本地方法栈.java堆.方法区.运行时常量池. 1.程序计数器 2.java虚拟机栈 3.本地方法栈 4.java堆(新生代和老年代) 5.方法区( ...

  3. JVM学习第一天(虚拟机的前世今生与与Java的内存区域)

    其实说JVM的时候有很多人会懵, 也很不理解,我会写Java代码就可以了,我干嘛要学这个,其实不是的,学习JVM是很有必要性的; 为什么要了解JVM 1:写出更好,更健壮的Java程序; 2:提高Ja ...

  4. java虚拟机内存区域的划分以及作用详解

    序言 为什么有时候学着学着会突然之间觉得一切度是那么无趣,男的每个月也有那么几天难道?哈哈,不然是什么,我还是要坚持,可以做少一点,但是不能什么度不做.总会过去的,加油 --WH 一.运行时数据区 什 ...

  5. 【转】Java之 内存区域和GC机制

    转自:Leo Chin 目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage ...

  6. Java虚拟机内存区域堆(heap)的管理

    在上一节中Java 出现内存溢出的定位以及解决方案 中对于Java虚拟机栈以及方法区的内存出现的异常以及处理方式进行了解析,由于Java虚拟机对于堆的管理十分复杂,并且Java虚拟机中最基本的内存区域 ...

  7. 总结Java虚拟机内存区域模型

    本篇文章主要来总结一下Java虚拟机内存的各个区域,以及这些区域的作用.服务对象以及其中可能产生的问题,作为大家的面试宝典. 首先我们来看一下Java运行时的数据区域,Java虚拟机在执行Java程序 ...

  8. 一、java虚拟机内存区域

    内存区域 java虚拟机在java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.java虚拟机规范将JVM管理的内存分为:程序计数器.本地方法栈.Java虚拟机栈.方法区.Java堆.如下 ...

  9. JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)

    1.内存区域划分 根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收.根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法.大批对象死去.少量 ...

随机推荐

  1. Springcloud 2.x 版本 分布式配置中心

    一.什么是分布式配置中心? 就是为微服务架构中的微服务提供集中化的外部配置支持,配置中心为各个微服务应用的所有环境提供了中心化的外部配置(可能比较难理解,想知道是什么意思就要知道为什么这么配置:这么配 ...

  2. 如何通过PHP将excel的数据导入MySQL中

    在开发PHP程序时,很多时候我们会有将数据批量导入数据库的需求,如学生信息批量添加到数据库中,而事先用excel编排好,对excel实行操作,便是我们比较常用的选择方式. 在对excel的操作中,ph ...

  3. HNUSTOJ-1639 分糖果(几何)

    1639: 分糖果 时间限制: 1 Sec  内存限制: 128 MB提交: 261  解决: 118[提交][状态][讨论版] 题目描述 为了实验室的发展,吴大大采购了一箱零食O(∩_∩)O~~ 在 ...

  4. C语言--一维数组,字符数组

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zuoyou1314/article/details/30799519 watermark/2/tex ...

  5. js函数调用的几种方法

    js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方 ...

  6. 用eclipse怎么打war包?

    用eclipse怎么打war包? 在服务器上部署很多都是用war包进行部署的,eclipse是很友好的支持把java项目打成war包的,下面就把打war的经验写出来,供大家参考 百度经验:jingya ...

  7. CenterOS7中解决No package mysql-server available.

    CenterOS7中解决No package mysql-server available. 1.使用yum install -y mysql-server报错如下: [root@heyong_jd ...

  8. Ubuntu配置python操作

    Ubuntu16.04 安装python 查看当前python情况root@localhost:/# cd /root@localhost:/usr/bin# cd /usr/binroot@loca ...

  9. Apache HttpClient 读取响应乱码问题总结

    Apache HttpClient 读取响应乱码问题总结 setCharacterEncoding  Content-Type  HttpClient  起因 最近公司产品线研发人员调整,集中兵力做战 ...

  10. Django【第27篇】:ModelForm

    基于Form组件实现的增删改和基于ModelForm实现的增删改 一.ModelForm的介绍 ModelForm a. class Meta: model, # 对应Model的 fields=No ...