运行时数据区:

运行时数据区主要分五块,分别是Method Area , VM Stack , Native Method Stack ,

Heap , program Counter Register。

Program Counter Register :

程序计数器是一小块内存空间,可以看作是当前线程所执行字节码的行号指示器。字节码解释器工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,各类基础功能也都是要依赖这个计数器来实现。

Java虚拟机的多线程是通过线程之间轮流切换并分配处理器的执行时间来实现的。也就是说,任何一个确定的时刻,一个处理器都只执行一个线程。因此为了保证线程切换的正确,每一个线程都有一个程序计数器,各个计数器互相不影响,独立存储。(线程私有内存)

如果线程在执行的是Java方法,那么程序计数器指向正在执行的字节码指令地址;如果一个线程执行的是Native方法,计数器值为空(Undefined)。

Java virtual Machine Stack:

和程序计数器一样,Java虚拟机栈也是线程私有的。它的生命周期与线程相同。虚拟机栈描述的是java方法执行的内存模型:

每个方法在执行的同时都会创建一个Stack Frame 用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用直到执行完成的过程,就对应着一个Stack Frame在虚拟机栈中入栈出栈的过程。

许多java程序员口中的栈,指的就是虚拟机栈的局部变量表。局部变量表存放了编译期可知的各种数据类型,包括8种基本类型和对象引用。

Reference类型:它不等同与对象本身,可能是一个指向对象起始地址的指针,也可能是指向一个对象的句柄(二级指针)或与此对象相关的位置,还有可能指向一条字节码指令的地址。

一个局部变量空间占32位,局部变量表在编译期完成分配。当进入一个方法时,这个方法需要在Stack Frame 中分配多大的局部变量空间是已经确定了的,此后大小也不会变化。

Java虚拟机规范中定义了两种异常:

1 )StackOverflowError :线程请求的栈深度大于虚拟机所允许的深度。(递归调用)

2)OutOfMemoryError : 大部分的虚拟机都支持空间的动态扩展,而如果扩展时无

法申请到足够的内存,就会抛出此异常。

Native Method Stack

本地方法栈与虚拟机栈的区别就是,虚拟机栈为执行Java字节码服务,本地方法栈为虚拟机使用到的Native方法服务。

虚拟机规范并没有对本地方法栈做使用方式和数据类型的强制规定,所以具体的虚拟机可以自由实现它。

Java Heap

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存的唯一目的就是存放对象的实例,几乎所有的对象实例(包括数组)都放在这里分配内存。

Java堆可以处于物理上的不连续的空间(逻辑空间连续即可),实现时,既可以固定大小,也可以是可扩展的。

当堆中没有内存完成实例分配,并且堆也无法扩展时,会抛出OutOfMemoryError。

Method Area

Method Area和堆一样是各个线程共享的内存区域。它用于存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

Method Area 也叫Non-Heap,很多人更愿意把它称为Permanent Generation(永生代),事实上,有的虚拟机设计者选择吧GC分代收集扩展到方法区,或者说使用永生代实现方法区,这样JavaGC就可以像管理Heap一样管理MethodArea,省去了专门为MethodArea专门写GC的麻烦。而永生代实现方法区并不是一个好主意,因为更容易出现内存溢出。现在逐渐开始采用Native Memory来实现方法区。

Runtime Constant Pool

运行时常量池是方法区的一部分。Class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是Constant Pool Table(常量池)用于存放编译期生成的各种字面量和符号引用。Constant Pool Table 将会在类加载后进入方法区的运行时常量池中存放。

Runtime Constant Pool 相对于Class 文件常量池的一个重要特征就是具备动态性。Java中常量并不是只有在编译期才能产生,也就是并非只有置入Class常量池中的内容才能进入方法区的运行时常量池,运行期间也可以将新的常量放入池中。这种特性被利用的比较多的就是String的intern()方法。

Direct Memory

Direct Memory不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存。但这并非内存也被频繁使用,而且可能导致OutOfMemoryError。

直接内存不会受堆大小的限制。由于经常忽略直接内存,所以经常在动态扩展时导致出现OutOfMemoryError异常。

Java JVM 内存空间解析的更多相关文章

  1. Java JVM 内存泄漏--全解析和处理办法 [ 转载 ]

    Java JVM 内存泄露——全解析和处理办法 [转载]   @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a         JA ...

  2. JVM内存区域解析

    引言 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间.有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的 ...

  3. 深入探究JVM(1) - Java的内存区域解析

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

  4. [ 转载 ] Java Jvm内存介绍

    一.基础理论知识 1.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止.你在同一台机器上 ...

  5. java jvm内存管理/gc策略/参数设置

    1. JVM内存管理:深入垃圾收集器与内存分配策略 http://www.iteye.com/topic/802638 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想 ...

  6. Java jvm 内存回收机制

    http://blog.csdn.net/yaerfeng/article/details/51291903 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方 ...

  7. JVM内存结构解析

    月初的时候个人网站到期了,不想再折腾重新建站了,以后还是来第三方博客写文章吧,可以省去很多问题.之前写的文章也不是很多,备份懒得做了,从头开始吧.博文仅仅是用来记录和学习总结,如有错误之处请帮忙指正! ...

  8. JVM内存空间划分与作用详解

    在之前已经对Java的字节码进行了非常详细而又系统的学习了,接下来开启jvm内存相关的新篇章,在一个新知识开头之前肯定得理论化的对其进行一个整体的介绍,所以摒弃浮躁,先来看看相关的理论,主要是看一下J ...

  9. 全网最硬核 Java 新内存模型解析与实验单篇版(不断更新QA中)

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

随机推荐

  1. sql2012,返回数据多时不走索引

    当数据达到一定值时,都会走表扫描旧版如SQL2005时就有计算选择性的比例为 满足条件的行数/总行数<=0.7181,会走索引,其它会走表扫描有兴趣可以自己去不同版本中去测试 Roy Wu(吴熹 ...

  2. TP5.0:的安装与配置

    在网址中输入:localhost/安装TP5的文件夹/public/ 入口文件位置:public/index.php: 最新版本中,新建的文件夹是没有模型和视图的,需要自行添加没有的文件: 添加前: ...

  3. Dll注入:Ring3 层 APC注入

    APC,即Asynchronous procedure call,异步程序调用APC注入的原理是:在一个进程中,当一个执行到SleepEx()或者WaitForSingleObjectEx()时,系统 ...

  4. 解决MVC运行controller的时候只有有参构造函数但是程序一定要走无参构造函数的方法

    方法如下 https://www.codeproject.com/Articles/560798/ASP-NET-MVC-Controller-Dependency-Injection-for-Be

  5. python实现栈的算法

    以下来源“悟空”的讲课视频,我只是对内容加深以下理解,做一些说明: 栈作为一种数据结构,是一种只能在一端进行插入和删除操作.它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要 ...

  6. python基础一 day16 内置函数

    # 数据类型 :int bool ...# 数据结构 : dict list tuple set str reversed()l = [1,2,3,4,5]l.reverse()print(l)l = ...

  7. 2018.5.30 Oracle数据库PLSQL编程---游标的使用

    显示游标的步骤 /* 显示游标处理步骤 1.声明游标 语法结构:cursor 游标名称 is SQL 语句; 2.打开游标 语法结构:open游标名称; 3.提取数据 语法结构:fetch 4.关闭游 ...

  8. 分布式版本控制系统git

    最近看到这篇文章,简洁易懂,特摘抄至https://www.cnblogs.com/bgwhite/p/9403233.html 供大家提供参考. git可以说是世界上最先进的版本控制系统,大多语句的 ...

  9. CentOS系统下安装Redis

    1. 安装C语言环境 yum install gcc-c++ 2.下载Redis安装包 http://download.redis.io/releases/redis-3.2.9.tar.gz 3.解 ...

  10. 《GPU高性能编程CUDA实战中文》中第四章的julia实验

    在整个过程中出现了各种问题,我先将我调试好的真个项目打包,提供下载. /* * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. ...