前言

在Java语言开发过程中,out of memory错误是很常见的一种错误。对于JVM的内存结构有更深入的了解,更更好的帮我们排查此类问题,有效的避免此类问题发生。在JAVA 8中内存结构有进行了改变,Metaspace替代了PermGen。

内存结构简介

JVM的内存结构如下图所示:(图片来源于网络)

JVM的内存结构大概分为:
堆(heap):线程共享,所有的对象实例以及数组都要在堆上分配。回收器主要管理的对象。
方法区(MEATHOD AREA):线程共享,存储类信息、常量、静态变量、即时编译器编译后的代码。
PC寄存器(PC Register):线程私有。指向下一条要执行的指令。
方法栈(JVM Stack):线程私有、存储局部变量表、操作栈、动态链接、方法出口,对象指针。
本地方法栈(NATIVE METHOD STACK):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。

各区域详细说明

先看一张图,这张图能很清晰的说明JVM内存结构的布局和相应的控制参数:(图片来源于网络)

堆的作用是存放对象实例和数组。堆从结构上来分,可以分为新生代和老生代。而新生代又可以分为Eden 空间、From Survivor 空间(s0)、To Survivor 空间(s1)。 所有新生成的对象首先都是放在年轻代的。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。

控制参数
-Xms设置堆的最小空间大小。-Xmx设置堆的最大空间大小。-XX:NewSize设置新生代最小空间大小。-XX:MaxNewSize设置新生代最小空间大小。

垃圾回收
此区域是垃圾回收的主要操作区域。

异常情况
如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。

方法区

方法区(Method Area)与Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java 堆区分开来。
很多人愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价,仅仅是因为HotSpot虚
拟机的设计团队选择把GC 分代收集扩展至方法区,或者说使用永久代来实现方法区而已。对于其他虚拟机(如BEA JRockit、IBM J9 等)来说是不存在永久代的概念的。在Java8中永生代彻底消失了。

控制参数
-XX:PermSize 设置最小空间 -XX:MaxPermSize 设置最大空间

垃圾回收
对此区域会涉及但是很少进行垃圾回收。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说这个区域的回收“成绩”比较难以令人满意。

异常情况
根据Java 虚拟机规范的规定, 当方法区无法满足内存分配需求时, 将抛出
OutOfMemoryError 异常。

PC计数器

它的作用可以看做是当前线程所执行的字节码的行号指示器。

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

方法栈

每个线程会有一个私有的栈。每个线程中方法的调用又会在本栈中创建一个栈帧。在方法栈中会存放编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不等同于对象本身。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

控制参数
-Xss控制每个线程栈的大小。

异常情况
在Java 虚拟机规范中,对这个区域规定了两种异常状况:
将抛出StackOverflowError: 异常线程请求的栈深度大
于虚拟机所允许的深度时抛出;
OutOfMemoryError 异常: 虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出。

本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其
区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则
是为虚拟机使用到的Native 方法服务。

控制参数
在Sun JDK中本地方法栈和方法栈是同一个,因此也可以用-Xss控制每个线程的大小。

异常情况
与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError 和OutOfMemoryError
异常。

参考资料

http://blog.chinaunix.net/uid-9789791-id-3350463.html

我的微信

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内存结构,运行机制

    三月十号,白天出去有事情出去了一天,晚上刚到食堂就接到阿里电话, 紧张到不行,很多基础的问题都不知道从哪里说了orz: 其中关于JVM内存结构,运行机制,自己笔记里面有总结的,可当天还是一下子说不出来 ...

  5. JVM内存结构简单认知

    关于JVM的面试传送门:https://blog.csdn.net/shengmingqijiquan/article/details/77508471 JVM内存结构主要划分为:堆,jvm栈,本地方 ...

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

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

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

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

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

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

  9. JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别

    JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一.  理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...

随机推荐

  1. C++仿函数(functor)详解

    C++仿函数(functor)详解 所谓的仿函数(functor),是通过重载()运算符模拟函数形为的类. 因此,这里需要明确两点: 1 仿函数不是函数,它是个类: 2 仿函数重载了()运算符,使得它 ...

  2. Android HandlerThread 使用

    HandlerThread 继承了 Thread,添加了 looper,queue 的支持.可以为 Handler 提供线程服务,并可对 执行的任务进行简单的管理. Handler 默认工作在主线程, ...

  3. The type xxx cannot be resolved. It is indirectly referenced from required .class files

    项目A中引入一个jar包B,在项目A中调用项目B,出现如下错误提示:   大致意思是:这上面所需的包是间接引用的,即A项目调用B项目,B项目又引用了另外一个包C,而这个包现在不在你的A项目的引用中. ...

  4. Android权限安全(7)binder,service,zygote安全相关简介

    binder 提供服务的service中的binder thread 检查调用者的uid 不是root,system就异常. service 也检查调用者的uid 不是root,system,只能注册 ...

  5. Regex Failure - Bug Fixing #2

    http://www.codewars.com/kata/55c423ecf847fbcba100002b/train/csharp Oh no, Timmy's received some hate ...

  6. 转载:Unobtrusive JavaScript in ASP.NET MVC 3 隐式的脚本在MVC3

    Unobtrusive JavaScript 是什么? <!--以下是常规Javascript下写出来的Ajax--> <div id="test"> &l ...

  7. 【C#学习笔记】获得本机IP

    using System; using System.Net; namespace ConsoleApplication { class Program { static void Main(stri ...

  8. 开发ffmpeg/live555常见问题错误及解决方法

    #include <iostream>using namespace std;extern "C" {#include <libavcodec/avcodec.h ...

  9. crtmpserver流媒体服务器的介绍与搭建

    crtmpserver流媒体服务器的介绍与搭建 (2012-02-29 11:28) 标签:  crtmpserver  C++ RTMP Server  rtmp  Adobe FMS(Flash ...

  10. MySQL基础之第2章 Windows平台下安装与配置MySQL

    2.1.msi安装包 2.1.1.安装 特别要注意的是,安装前要删除原来的my.ini和原来的data目录,改名也行,不然在最后一步会“apply security settings”报个1045错误 ...