Java和C++之间有一堵由内存管理和垃圾收集技术所围成的“高墙”,墙外的人想进去,墙内的人却想出来。  ------摘自《深入理解Java虚拟机》

作为一个Java程序员,因为虚拟机的好处,在开发过程中一般不用关心内存分配和垃圾回收方面的内容,这就让我在跟C++的朋友聊天或沟通的时候,总觉得自己是个假的程序员,虽然我们不用自己动手去做这两件事情,但还是很有必要去了解一下这方面的原理,这样万一真碰到内存溢出的问题,就不至于束手无策了。下面是通过看书总结的一些内容。

一、Java内存区域划分

Java虚拟机在执行Java程序的过程中,会把它所管理的内存区域划分成不同的数据区域,没有数据区域都有各自的功能、创建和销毁时间,有些随着虚拟机的启动而产生,有些随着用户线程的创建和结束而产生和销毁,根据《Java虚拟机规范》的规定,Java虚拟机所管理的内存将会包含下面几个部分:

从上图可知,Java虚拟机内存主要由线程共享的堆内存、方法区和线程私有的虚拟机栈、本地方法栈和程序计数器五个运行时数据区。

 二、各运行时数据区的功能介绍

1、程序计数器

1)程序计数器是当前线程所执行的字节码的行号指示器,存放下一个要执行的字节码位置;

2)此内存区域是唯一一个在Java虚拟机规范中没有任何OutOfMemoryError异常的区域;

3)线程私有

2、Java虚拟机栈

1)Java虚拟机栈是方法执行的内存模型,通俗点说就是执行方法是进行内存管理的区域。

方法执行时,会创建一个栈帧,用于存储方法中的局部变量、操作数、动态链接和方法出口等信息,方法的调用执行过程就是一个栈帧在虚拟机栈中进行入栈出栈的过程;

2)线程私有,随着线程的开始而创建,线程的结束而销毁;

3)通常所说的Java栈内存就是指Java虚拟机栈中的局部变量表,它存放了编译期可知的基本类型(boolean、byte、char、short、int、long、float、dounle)、对象引用和returnAddress类型。局部变量的大小在程序编译期就已经完成,而且在方法执行期间不会被改变;

4)此区域可能发生的异常有:

StackOverflowError:当线程请求的栈深度超过Java虚拟机所允许的栈深度时,会发生栈溢出异常;

OutOFMemoryError:当虚拟机栈在动态扩展过程中没有申请到足够的内存时,会发生内存溢出异常;

3、本地方法栈

1)同虚拟机栈,本地方法栈也是Java方法执行的内存模型,区别在于虚拟机栈是为Java程序在虚拟机中执行服务的,而本地方法栈是为本地方法在Java虚拟机中执行服务的。在虚拟机规范中,对本地方法栈中的方法所使用的语言、使用方法和数据结构都没有强制规定;

2)线程私有

3)可抛出两种异常:

StackOverflowError:当线程请求的栈深度超过Java虚拟机所允许的栈深度时,会发生栈溢出异常;

OutOFMemoryError:当虚拟机栈在动态扩展过程中没有申请到足够的内存时,会发生内存溢出异常;

4、Java堆

1)堆内存是Java虚拟机所管理的内存中最大的一块;

2)线程共享,在虚拟机启动时创建;

3)用来存放对象实例和数组;

4)堆是垃圾收集器管理的主要区域,因此也称GC堆;

5)堆内存可扩展,可通过参数--Xmx和--Xms来设置最大堆内存和最小堆内存来控制;

6)如果堆中没有足够的内存来分配实例,且堆无法扩展时就会抛出OutOfMemoryError异常

5、方法区

1)同堆内存一样,方法区也是线程共享的内存区域;

2)用来存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;

3)根据Java虚拟机规范,当方法区无法满足内存分配需求时就会抛出OutOfMemoryError异常

6、直接内存

这部分内存既不是Java虚拟机运行时数据区,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也会被频繁使用,而且还有可能引起OutOfMemoryError异常。本机内存的分配不会受到Java虚拟机内存分配的影响,但是当虚拟机中各区域的内存之和大于本机内存的话,就会导致动态扩展时出现OutOfMemoryError异常

以上就是Java虚拟机中的内存模型及各内存在程序运行过程中所扮演的角色或所起的作用。下节将会总结各个内存区域出现内存溢出异常的原因和解决方法。

备注:以上内容来源于《深入理解Java虚拟机》,根据自己的理解来总结,有些内容和书本内容相同是因为只有这么描述才比较好懂,毕竟大神还是大神,是颜色不一样的烟火!!

Java虚拟机系列(一)---Java内存划分的更多相关文章

  1. 【java虚拟机系列】java虚拟机系列之JVM总述

    我们知道java之所以能够快速崛起一个重要的原因就是其跨平台性,而跨平台就是通过java虚拟机来完成的,java虚拟机属于java底层的知识范畴,即使你不了解也不会影响绝大部分人从事的java应用层的 ...

  2. java虚拟机学习记录(内存划分、垃圾回收、类加载等机制)

    一直以来觉得虚拟机是Java最难的一部分,涉及最底层的原理,学起来难度很大,而且工作中基本上用不到这些原理,所以对这部分“敬而远之”.现如今工作五年了,从Java基础到算法.数据结构.网络.数据库.设 ...

  3. 【java虚拟机系列】java中类与对象的加载顺序

    首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...

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

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  5. 【java虚拟机系列】从java虚拟机字节码执行引擎的执行过程来彻底理解java的多态性

    我们知道面向对象语言的三大特点之一就是多态性,而java作为一种面向对象的语言,自然也满足多态性,我们也知道java中的多态包括重载与重写,我们也知道在C++中动态多态是通过虚函数来实现的,而虚函数是 ...

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

    文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...

  7. Java虚拟机系列——检视阅读

    Java虚拟机系列--检视阅读 参考 java虚拟机系列 入门掌握JVM所有知识点 2020重新出发,JAVA高级,JVM JVM基础系列 从 0 开始带你成为JVM实战高手 Java虚拟机-垃圾收集 ...

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

    几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB,相邻 ...

  9. <<深入Java虚拟机>>-第二章-Java内存区域-学习笔记

    Java运行时内存区域 Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域.每个区域都有自己的用途,创建以及销毁的时间.有的随着虚拟机的启动而存在,有的则是依赖用户线程来 ...

随机推荐

  1. 牛客多校第五场 H subsequence 2 拓扑排序

    题意: 给你长度最长为1000的字符串,这个字符串中最多有10种字母,每次给你两种字母,输出这两种字母在字符串中的相对位置,问你这个字符串原本是什么样子,如果不存在则输出-1 题解: 把整个字符串看作 ...

  2. 次短路 /// dijkstra oj1597

    题目大意: 给出一个有向图,求从 顶点a 到 顶点b 的次短路. 第一行是2个正整数 n 和 e,表示该有向图的顶点数和边数.3 < n ≤ 5000 , 3 < e < 40000 ...

  3. springcloud系列14 bus的使用

    首先springcloud_bus原理: (1)完整流程:发送端(endpoint)构造事件event,将其publish到context上下文中(spring cloud bus有一个父上下文,bo ...

  4. spring基于xml的IOC环境搭建和入门

    配置pom.xml的依赖 <packaging>jar</packaging> <dependencies> <dependency> <grou ...

  5. SPOJ10707 COT2-Count on a tree II

    COT2 - Count on a tree II 中文题意 离线询问一颗树上路径(u,v)中经过所有点的权值的种类数. 题解 树上莫队.即在树的欧拉序列上进行莫队.同一个点加第一次时增加,第二次时减 ...

  6. Apache下更改.htaccess文件名称

    有时候我们需要更改.htaccess的名称以解决一些问题 比如:Eclipse下是不显示点开头的文件的 所以我们可以使用  Apache的AccessFileName来更改此配置文件的名称 Acces ...

  7. 学习 debug

    要在代码编辑器中设置源代码断点,有以下 4 种操作方式. (1) 把光标移到要设为断点的行上,按下 F5 键. (2) 用鼠标左键单击要设为断点的行的最左端. (3) 用鼠标右键单击要设为断点的行,在 ...

  8. Django问题2

    接触django是从上个月开始,学习python时间也不长,但我经常在社区看看别人发表的文章,早上看到一篇不错的博客,却一直不能访 问,最终从bing的缓存里找到,因为害怕丢失和忘掉,所以顺便翻译过来 ...

  9. BZOJ2594:水管局长数据加强版

    Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...

  10. WCF进阶:扩展bindingElementExtensions支持对称加密传输

      前面两篇文章WCF进阶:将编码后的字节流压缩传输和WCF 进阶: 对称加密传输都是实现了自定义编码,那两个例子中托管服务或者客户端调用都采用的代码实现,WCF更友好的方式是在app.config或 ...