普通进程栈区,在JVM一般仅仅用做线程栈,如下图所示

首先是永久代。永久代本质上是Java程序的代码区和数据区。Java程序中类(class),会被加载到整个区域的不同数据结构中去,包括常量池、域、方法数据、方法体、构造函数、以及类中的专用方法、实例初始化、接口初始化等。这个区域对于操作系统来说,是堆的一个部分;而对于Java程序来说,这是容纳程序本身及静态资源的空间,使得JVM能够解释执行Java程序。

其次是新生代和老年代。新生代和老年代才是Java程序真正使用的堆空间,主要用于内存对象的存储;

那么这些区域如何对应JVM的内存模型呢,首先看一张经典的JVM内存模型图:

线程栈:在JVM中用做线程栈,每个线程都会在这个区域开辟私有栈

程序计数器是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支循环,跳转,异常处理,线程恢复等基础功能,特别注意的是,如果线程正在执行的是一个java方法那这个计数器记录的是字节码指令的地址(位置),如果是执行的是Native方法,这个计数器为空

程序计数器该部分内存是唯一不会发生OutOfMemoryError异常的区域

java虚拟机栈,也在这个线程栈中,线程私有,每个方法执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息.

局部变量表,存放了编译期可知的各种基本数据类型(boolean,byte,char short,int float,long,double),对象引用(reference,指向对象的指针,或者代表对象的句柄)和returnAddress类型

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

本地方法栈,与虚拟机栈的作用非常相似,只不过是服务于Native方法,也会抛出两种异常

inux的普通进程所使用的堆区,在jvm(Hotspot)进程中分为永久新生老年代三块区域

永久代,对应于 jvm的方法区,

方法区:用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码,等数据.要特别注意的是.方法区和永久代并不是等价的,这要取决于虚拟机的类型,紧紧是因为HotSpot使用永久代来实现方法区.对于其他虚拟机并不存在永久代的概念,

运行时常量池是方法区的一部分,因此它也在永久代,用于存储编译期间生成的各种字面量和符号引用,什么叫字面量呢,就是int i =1;这个1就是字面量,String str= "abc";这个abc是字面量,什么叫符号引用呢,就是在一个类中Student stu = new Student("张三",28) new出来的Student对象在编译后未加载前显然不知道其实际内存地址,因此在class文件中用一串无异议的符号来代替对象的内存首地址,等class文件经过一系列的加载检验之后分配完内存,会将符号引用替换成直接引用

新生代和老年代

Java堆:新生代和老年代才是对应于JVm内存模型中的java堆,它是被所有线程共享的一个内存区域,在虚拟机启动时创建.它的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,包括数组

java堆是垃圾收集器管理的主要区域,因此,很多时候也被称为GC堆,由于现在收集器基本都采用分代收集算法,所以Java堆细分为新生代和老年代;再细致一点的有Eden空间,FROM Survivor空间,To Survivor空间等.

从内存分配的角度来看,线程共享的java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer TLAB),进一步划分是为了更好的回收内存,或者更快的分配内存.

根据JVM规范,java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的就可以,如果在堆中内有内存完成实例分配,并且对无法扩展出足够的内存,将会抛出OutOfMemoryError异常

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

在jdk1.4中新加入了NIO类,引入了一种基于通道(Channel)与缓冲区(BUffer)的IO方式,它可以使用Native函数库直接分配内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存引用进行操作,这样能在一些场景中显著提高性能,因为避免了Java堆和Native堆中来回复制数据.如下图:NIO使用的堆外内存

显然,本机直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定还是会受到本机总存的(包括RAM以及swap区域或者分页文件),大小以及处理器寻址空间的限制.服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息.但经常忽略直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常

https://mp.weixin.qq.com/s?__biz=MzI4NTEzMjc5Mw==&mid=2650554703&idx=1&sn=4b2ce0d3fa9017adb2dac9843f097882&chksm=f3f833d9c48fbacf242749ec8f40197d9ea5463dc46f47afc62fd93b3fe4f433a723ceddd515#rd

从linux进程角度看JVM内存模型的更多相关文章

  1. 【JVM】上帝视角看JVM内存模型,分而治之论各模块详情

    1. 上帝视角 [树看JVM] [图看JVM] 2. 分而治之 2.1 堆区 构成:堆区由新生代和老年代组成,新生代中包含伊甸区(Eden).幸存者区(survivor from .survivor ...

  2. JVM内存模型你只要看这一篇就够了

    JVM内存模型你只要看这一篇就够了 我是一只孤傲的鱼鹰 让我们不厌其烦的从内存模型开始说起:作为一般人需要了解到的,JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这 ...

  3. Inside JVM 内存模型

    Inside JVM 内存模型 来源  原文:https://blog.csdn.net/silentbalanceyh/article/details/4661230 参考:IBM开发中心文档,&l ...

  4. JVM内存模型 三

    本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏   1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...

  5. JVM内存模型与GC算法(简介)

    JVM内存模型如上图,需要声明一点,这是<Java虚拟机规范(Java SE 7版)>规定的内容,实际区域由各JVM自己实现,所以可能略有不同.以下对各区域进行简短说明. 1.1程序计数器 ...

  6. JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集

    (转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...

  7. [转]JVM内存模型

    最近排查一个线上java服务常驻内存异常高的问题,大概现象是:java堆Xmx配置了8G,但运行一段时间后常驻内存RES从5G逐渐增长到13G #补图#,导致机器开始swap从而服务整体变慢.由于Xm ...

  8. JVM内存模型小结

    JVM运行时的数据区域划分图如下,该图是JVM内存模型最主要的内容. 从图中可以看出来,JVM将内存主要划分为五个部分:程序计数器.Java虚拟机栈.本地方法栈.Java堆和方法区.这些被划分为用途不 ...

  9. JVM内存模型和性能优化 转

    JVM内存模型和性能优化 JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于 ...

随机推荐

  1. IntelliJ IDEA 出现" java: 程序包javax.servlet不存在、 java: 程序包javax.servlet.annotation"等错误

    在IDEA中建立Servlet使用javax.servlet.http.HttpServlet等类时,出现了如下错误: 原因:IntelliJ IDEA 没有导入 servlet-api.jar 这个 ...

  2. tomcat安全基线

    为了符合tomcat安全基线,需要做一下加固: 1.管理用户的密码加密:<摘要算法加密tomcat登录密码> 管理用户在conf/tomcat-users.xml中配置,密码一般是明文形式 ...

  3. Kubernetes 使用 Weave Scope 监控集群(十七)

    目录 一.安装 二.使用 Scope 2.1.拓扑结构 2.2.在线操作 2.3.强大的搜索功能 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所 ...

  4. centos7 spark2.3.1集群搭建

    1.安装jdk 2.安装scala 参照jdk的安装 3.ssh 免密码登录 4.安装hadoop 以上四步请参照   centos7 安装hadoop2.7.6(分布式) 5.安装spark  1) ...

  5. HMAC哈希消息认证码

    收藏 137 14   hmac 编辑 HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出.   中文名 哈希消息认证码 外文名 H ...

  6. Word 插入页码 -- 视频教程(7)

    1. 以本科做的一个课程设计为例 >> 视频教程链接:B站,速度快,清晰 未完 ...... 点击访问原文(进入后根据右侧标签,快速定位到本文)

  7. flask---快速使用

    初识falsk django是大而全面的框架,flask是个轻量级的框架. flask快速开发网站 flask可以使用很少的代码就可以直接完成一个项目(6,7行代码),如下: from flask i ...

  8. Spark实战电影点评系统(一)

    一.通过RDD实战电影点评系统 日常的数据来源有很多渠道,如网络爬虫.网页埋点.系统日志等.下面的案例中使用的是用户观看电影和点评电影的行为数据,数据来源于网络上的公开数据,共有3个数据文件:uers ...

  9. 代理服务器支持https(转)

    原标题:让代理服务器支持HTTPS很难吗?    http://www.site-digger.com/html/articles/20151203/107.html

  10. 小程序canvas绘制base64数据格式图片

    翻了微信小程序官方文档,看了看画板drawImage的用法,官方对所要绘制的图片资源路径并没有很详细,模棱两可,没说支持什么格式的路径.今天我就试一下支不支持base64格式的图片 随便找张图片从网上 ...