Java虚拟机系列之Java内存结构简介

本文我们将讲解Java虚拟机中各个区域以及各个区域的作用。

一.程序计数器
什么是程序计数器,有什么作用?
程序技术器是一块比较小的内存区域,主要当做是线程中所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选取下一个执行的字节码命令,分支、循环、跳转等基础功能都是依赖这个程序计数器来完成。

有什么特点?
Java虚拟机中的多线程是通过线程轮流切换分配处理器执行时间的方式来实现的,所以为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,所以是线程私有的。

注意:
如果线程执行的是Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器的值为空,此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemory的情况的区域

二.Java虚拟机栈
Java虚拟机栈是干嘛的?
Java虚拟机栈描述的是Java内存模型,每个方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行结束对应着一个栈帧在虚拟机栈中入栈出栈的过程。

有什么特点?
Java虚拟机栈是线程私有的,而且生命周期和线程相同。

注意:
如果线程请求的栈的深度大于虚拟机所允许的深度,将抛出StackOverFlowError异常;如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够多的内存,就会抛出OutOfMemoryError异常。

三.本地方法栈
与虚拟机栈发挥的功能类似,区别不过是虚拟机栈为虚拟机执行Java方法,本地方法栈为虚拟机用到的Native方法服务。本地方法栈也会抛出StackOverFlowError和OutOfMemoryError异常。

四.Java堆
什么是Java堆,有什么作用?
Java堆是Java虚拟机中所管理内存中最大的,是所有线程共享的一块内存区域,在虚拟机启动的时候创建,目的是存放对象实例。

有什么特点?
几乎所有的对象实例都在这里分配内存,因此这也是垃圾收集器管理最主要的区域,而且Java堆可以处于物理不连续的内存空间,只要逻辑连续即可

1、Java堆中还细分新生代和老年代,然后新生代中又分为Eden区域、From Survivor空间、To Survivor空间等。

2、这里的Java堆的垃圾回收算法是使用了分代收集算法,即新生代中使用“复制”算法,而老年代中使用“标记-清理”算法或“标记-整理”算法。

注意:
当前主流虚拟机都是可扩展来实现的(通过-Xms和-Xmx来控制),如果堆中没有内存完成实例,并且堆也无法再扩展时,会抛出OutOfMemoryError异常。

五.方法区
方法区的作用是什么?
方法区是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。

为啥说方法区不等价于永久区?
方法区不等价于永久代,只是HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,是为了HotSpot垃圾收集器可以像管理Java堆一样管理这部分内存,能够省去专门为方法区编写内存管理代码的工作,但是这样也会更容易造成内存溢出的问题(永久代可以用-XX:MaxPermSize设置上限),所以在JDK1.7的HotSpot已经把永久代的字符串常量池移出,移到了Java Heap区,可在 《深入解析String#intern》 了解

运行时常量池有什么作用?
运行时常量池也是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分将在类加载后进入方法区的运行时存放。

运行时常量池的特点?
Java虚拟机对Class文件每一部分的格式都有严格规定,每一个字节用于存储哪种数据都必须符合规范上的要求才会被虚拟机认可、装载和执行,然而对于运行时常量池却没做任何要求
运行时常量具有动态性,可以在运行期间将新的常量放入池中,比如String的intern()方法
六.直接内存
直接内存是Java虚拟机的内存吗?
直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范定义的内存区域,是使用本机的内存,又名堆外内存。

怎么在Java中使用堆外内存?
在JDK1.4中的NIO类,引入了基于通道(Channel)与缓冲区(Buffer)的I/O方式,可以使用Native函数库来直接分配堆外内存,然后在Java堆中使用DirectByteBuffer对象来作为这块内存的引用进行操作。

注意:
虽然堆外内存不受Java堆大小的管理,但是受本机总内存以及处理器寻址空间的限制。在服务器管理员配置虚拟机参数的时候,可以通过-Xmx等来配置Java虚拟机最大内存,但经常忽略直接内存,导致各个内存区域总和大于物理内存限制,导致OutOfMemoryError异常。

如果本文有什么疑问或者是错误,欢迎指出留言,互相学习

原文地址:http://blog.51cto.com/13792737/2129892

时间: 2024-10-03 23:00:15

Java虚拟机系列之Java内存结构简介的相关文章

Java虚拟机详解02----JVM内存结构

主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启动时,是由java命令/javaw命令来启动的. 二.JVM基本结构: JVM基本结构图: <深入理解Java虚拟机(第二版)>中的描述是下面这个样子的: Java中的内存分配: Java程序在运行时,需要在内存中的分配空间.为了提高运算效率,就对数据进行了不同空间的划分,因为每一片区域都有特定的处理数据方式和内存管理方式. 具体划分为如下5个内存空间:(非常重要) 栈:存放局部变量

【java虚拟机序列】java中的垃圾回收与内存分配策略

在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃圾回收(Garbage Collection,GC)是java语言的一大特色,在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理.而在C/C++中是需要程序员主动释放的,而在java中则交给JVM自动完成,既然是交给程序自动执行,那么这里就必须完成以下几件事:

深入理解java虚拟机系列(一):java内存区域与内存溢出异常

文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了开始.如果有什么错误或者遗漏,欢迎指出. 一.概述 先上一张图 这张图主要列出了Java虚拟机管理的内存的几个区域. 常有人把Java内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java内存区域的划分实际上远比这复杂,从上图就可以看出了.堆栈分法中所指的"栈"实际上只是虚拟机栈,或者说是虚拟机栈中的局部变量表部分.接下

深入理解java虚拟机系列(二):垃圾收集器与内存分配策略

第一篇,点这里  深入理解java虚拟机系列(一):java内存区域与内存溢出异常 先直接上结构图,笔记下一次补上,结构图如下:

Java虚拟机系列一:一文搞懂 JVM 架构和运行时数据区

前言 之前写博客一直比较随性,主题也很随意,就是想到什么写什么,对什么感兴趣就写什么.虽然写起来无拘无束,自在随意,但也带来了一些问题,每次写完一篇后就要去纠结下一篇到底写什么,看来选择太多也不是好事儿,更重要的是不成体系的内容对读者也不够友好.所以以后的博客尽量按系列来写,不过偶尔也会穿插其他的内容.接下来一段时间我会把写博客的重点放在 JVM (Java Virtual Machine) 和 JUC (java util concurrent ) 上,对 Java 虚拟机和 Java 并发编

&lt;&lt;深入Java虚拟机&gt;&gt;-第二章-Java内存区域-学习笔记

Java运行时内存区域 Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域.每个区域都有自己的用途,创建以及销毁的时间.有的随着虚拟机的启动而存在,有的则是依赖用户线程来启动和销毁. 程序计数器 程序计数器是一块很小的区域,可以看做是用来表示线程所执行到字节码的某一行的行号指示器. 在Java虚拟机中,多线程是线程之间轮流切换并分配处理器的执行时间来实现的,为了线程切换之后能够继续回到之前的代码行继续执行,所以每个线程都有一个“线程私有”的程序计数器. 如果线程正在

Java虚拟机运行时数据区结构

本文部分参考自<Java虚拟机规范(Java SE 7版)>的中译本和周志明的<深入理解Java虚拟机>,另加个人理解.原书对Java虚拟机运行时数据区描述只有6页,同时参考其他网络网资料,个人能力所限,不排除存在认知错误. JVM将程序运行期间使用的内存划分为若干个运行时数据区,其中一些会随着虚拟机启动而创建,随着虚拟机退出而销毁.另外一些与线程一一对应,随着线程开始而创建,随着线程结束而销毁.数据区划分如下图所示意: Java堆(Java Heap) 在JVM中,Java堆是可

Java虚拟机2:Java内存区域及对象

http://www.cnblogs.com/xrq730/p/4827590.html 几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB,相邻单位之间都是1024倍,1024为2的10次方,即 1Byte = 8bit,1K = 1024Byte,1M = 1024K,1G = 1024M,1T = 1024G 2.计算机存储元件 寄存器:中央处理器

java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)

前面学习ByteArrayInputStream,了解了“输入流”.接下来,我们学习与ByteArrayInputStream相对应的输出流,即ByteArrayOutputStream.本章,我们会先对ByteArrayOutputStream进行介绍,在了解了它的源码之后,再通过示例来掌握如何使用它. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_03.html ByteArrayOutputStream 介绍 ByteArrayOutpu