一、Java的内存区域划分

Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域。

Java的内存区域主要分为五部分:

  • 程序计数器(PC)
  • Java 虚拟机栈(JVM Stack)
  • 本地方法栈(Native Method Stack)
  • Java 堆内存(Java Heap)
  • 方法区(Method Area)

1.1、按照功能

1.2、按照内存是否共享

  • 类装载器(ClassLoader)(用来装载.class文件)
  • 执行引擎(执行字节码,或者执行本地方法)
  • 运行时数据区(方法区、堆、java栈、PC寄存器、本地方法栈),如下图:

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

1、程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的信号指示器。每一条JVM线程都有自己的PC寄存器在任意时刻,一条JVM线程只会执行一个方法的代码。该方法称为该线程的当前方法(Current Method)如果该方法是java方法,那PC寄存器保存JVM正在执行的字节码指令的地址,如果该方法是native,那PC寄存器的值是undefined。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。  

2、Java 虚拟机栈

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

详细见《JVM体系结构之四:虚拟机栈VM stack

3、本地方法栈

Java可以通过java本地接口JNI(Java Native Interface)来调用其它语言编写(如C)的程序,在Java里面用native修饰符来描述一个方法是本地方法。本地方法栈就是虚拟机线程调用Native方法执行时的栈,它与虚拟机栈发挥类似的作用。但是要注意,虚拟机规范中没有对本地方法栈作强制规定,虚拟机可以自由实现,所以可以不是字节码。如果是以字节码实现的话,虚拟机栈本地方法栈就可以合二为一,事实上,OpenJDK和SunJDK所自带的HotSpot虚拟机就是直接将虚拟机栈和本地方法栈合二为一的。

Java虚拟机规范规定该区域也可抛出StackOverFlowError和OutOfMemoryError。

4、Java 堆

这个区域用来放置所有对象实例以及数组。不过在JIT(Just-in-time)情况下有些时候也有可能在栈上分配对象实例。堆也是java垃圾收集器管理的主要区域(所以很多时候会称它为GC堆)。

从GC回收的角度看,由于现在GC基本都是采用的分代收集算法,所以堆内存结构还可以分块成:新生代和老年代;再细一点的有Eden空间、From Survivor空间、To Survivor空间等。如下图:

5、方法区

方法区是可供各条线程共享的运行时内存区域。存储了每一个类的结构信息,例如运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法

方法区创建时机:在虚拟机启动的时候创建。

方法区的容量:可以是固定大小的,也可以随着程序执行的需求动态扩展,并在不需要过多空间时自动收缩。方法区在实际内存空间中可以是不连续的。

见《JVM体系结构之三:方法区之1》和《JVM体系结构之三:方法区之2:常量池

6、直接内存

直接内存(Direct Memory)虽然不是程序运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但这部分内存也被频繁使用,而且它也可能导致OutOfMemoryError异常出现。

在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native方法库直接分配堆外内存,然后通过一个存储在Java堆里面的DirecByteBuffer对象作为这块内存的引用进行操作。这样能在某些应用场景中显著提高性能,因为它避免了在Java堆和Native堆中来回复制数据。

显然,本机直接内存的分配不会受到Java堆大小的限制,但是,还是会受到本机总内存(包括RAM及SWAP区或者分页文件)的大小及处理器寻址空间的限制,从而导致动态扩展时出现OutOfMemoryError异常。

7、执行引擎

将字节码即时编译 优化 为本地代码, 然后执行。

在了解完这些知识以后,就可以知道:类和对象在运行时的内存里是怎么样的?以及各类型变量、方法在运行时是怎么交互的?

在程序运行时类是在方法区,实例对象本身在堆里面。

方法字节码在方法区。线程调用方法执行时创建栈帧并压栈,方法的参数和局部变量在栈帧的局部变量表。

对象的实例变量和对象一起在堆里,所以各个线程都可以共享访问对象的实例变量。

静态变量在方法区,所有对象共享。字符串常量等常量在运行时常量池。

各线程调用的方法,通过堆内的对象,方法区的静态数据,可以共享交互信息。

各线程调用的方法所有参数传递、方法返回值的返回,都是使用栈帧里的操作数栈来完成的。

JVM内存结构之一--总体介绍的更多相关文章

  1. jvm系列(二):JVM内存结构

    JVM内存结构 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能 ...

  2. JVM内存结构之三--持久代

    本文会介绍一些JVM内存结构的基本概念,然后很快会讲到持久代,来看下Java SE 8发布后它究竟到哪去了. 基础知识 JVM只不过是运行在你系统上的另一个进程而已,这一切的魔法始于一个java命令. ...

  3. 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控

    如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...

  4. 【JVM】JVM内存结构 VS Java内存模型 VS Java对象模型

    原文:JVM内存结构 VS Java内存模型 VS Java对象模型 Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清 ...

  5. 【转】JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途. 其中有些区域随着虚拟机进程的启动而 ...

  6. jvm系列二、JVM内存结构

    原文链接:http://www.cnblogs.com/ityouknow/p/5610232.html 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemory ...

  7. JVM活学活用——Jvm内存结构

    Java内存结构: JVM内存结构主要是有三大块:堆内存.方法区和栈.堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分为三部分,Eden空间.From Survivor空间.To S ...

  8. JVM内存结构(转)

    所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能问题,那么这些问 ...

  9. java的线程安全、单例模式、JVM内存结构等知识学习和整理

    知其然,不知其所以然 !在技术的海洋里,前路漫漫,我一直在迷失着自我. 欢迎访问我的csdn博客,我们一同成长! "不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!" 博 ...

随机推荐

  1. java多态与异常处理——动手动脑

    编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”.“及格”.“中”.“良”.“优”的结论. 要求程序必须具备足够的健壮性,不管用户输入什 么样的内容,都 ...

  2. 关于C语言的输入-scanf、gets、getchar、getch、getline

    找工作刷题,重拾C语言,发现对键盘输入掌握很生疏,现总结各类输入函数使用方法和注意事项如下. 1.scanf("格式说明",变量地址列表) scanf("%s" ...

  3. 《Head First HTML&CSS》笔记

    void元素是指HTML页面中开始标记和结束标记之间没有任何内容的元素. 应当使用相对链接来链接同一网站中的页面,而用URL来链接其他网站上的页面. 浏览器读取计算机本地文件时会使用file协议.文件 ...

  4. 839. Optimal Marks - SPOJ

    You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...

  5. [笨木头FireFly01]入门篇1·最简单的服务端和客户端连接

    原地址:http://www.9miao.com/question-15-53938.html 最近一直在写游戏,几乎没有来写教程了,打算放慢一下脚步,学学新东西.那为嘛我要学FireFly呢? 之前 ...

  6. ajax跨域访问的解决方案

    今天的工作中要访问摄像机内部的一个web站点,这就涉及到jquery的ajax跨域访问的问题.我使用的是jquery1.7的版本,下面总结如下: 问题一:一开始用IE调试,总是返回No Transpo ...

  7. GridBagLayout:网格包布局管理器

    GridBagLayout:网格包布局管理器   GridBagLayout可以说是布局管理器Layout中最复杂的一个,其中涉及到的参数也比较得多,比如说: GridBagConstraints g ...

  8. WinAPI你知道多少?!(上千个,好多都没见过)

    http://www.cnblogs.com/vanver/archive/2013/06/13/NO-2013_06_13pm.html 播客开篇,讲讲废话:本篇播客只是推荐给热与钻研的同学们... ...

  9. POJ1328——Radar Installation

    Radar Installation Description Assume the coasting is an infinite straight line. Land is in one side ...

  10. SOCKS5协议

    SOCKS5 是一个代理协议,这种协议对本身所代理的内容并不关心,可用于穿越防火墙. 例如我有一台web服务器,用户可以登陆上去查询公司的关键数据,这样的服务器我肯定是不想放到公网上让别人能随便访问, ...