JVM模型及内存溢出
一、JVM截图及概念

图1:JVM虚拟机运行时数据区域概念模型
1、程序计数器:内存空间中的一块小区域,作为当前线程所执行的字节码的行号指示器,注:如果是native方法,计数器为空
2、虚拟机栈:线程私有,生命周期与线程相同,虚拟机栈描述的是Java方法执行的内存模型:创建栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息
3、本地方法栈:和虚拟机栈功能类似,虚拟机使用本地Native方法服务
4、Java堆:线程共享,用于存放对象,是GC的主要管理区域
5、方法区:线程共享,用于存储已被虚拟机加载的类信息,变量,静态变量,即时编译器编译后的代码等数据
6、运行时常量池:编译期生成的各种字面量和符号引用
7、直接内存:直接内存不属于虚拟机运行时数据区的一部分,但是这部分内存也会被频繁的使用,而且也会导致OutOfMemoryError的异常
在JDK1.4中引入的NIO类中,有一种基于通道和缓存区的I/O方式,可以使用native函数直接调用堆外内存,然后使用Java堆中的DirectByteBuffer对象来引用操作,可以提高JVM的性能
二、JVM中对象的创建
当JVM解析,遇到new指令时,JVM首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个类是否被加载、解析和初始化过。
如果没有,那必须先执行相应的类加载过程(加载,验证,准备,解析,初始化),在类加载检查通过后,JVM会对新生对象在Java堆中分配内存,内存的大小在类加载完成后才能够完全确定。Java内存的分配方式有:指针碰撞和空闲列表,他们的分配原则是根据JVM中堆是否规整决定的。
对象在内存中的布局可以分为3块区域:对象头(运行时数据【哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳】,类型指针【指向类元数据指针】)、实例数据和填充
三、JVM中对象的访问
在JVM中对象的访问主要使用:句柄和指针

图2:使用句柄访问对象

图3:使用指针访问对象
两种对象访问方式各有优势,使用句柄来访问的最大好处是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。使用直接指针访问方式的最大好处就是速度更快,它节省了一次指针定位的时间开销。HotSpot虚拟机使用的是直接指针访问的方式。句柄来访问的情况也十分常见。
四、Java中出现OutOfMemoryError的情况
在图1的JVM虚拟机运行时数据区域概念模型中存在程序计数器、虚拟机栈、本地方法栈、Java堆、方法区、运行时常量池、直接内存,除了程序计数器,其他的部分如果操作不当都会产生运行时内存溢出的问题,下面将对虚拟机栈、本地方法栈、Java堆、方法区、运行时常量池、直接内存的溢出情况作阐述:
1、Java堆溢出
一般创建的对象在堆中容纳不下就会溢出,当抛出内存溢出问题时,需要进一步确定到底是内存泄露还是内存溢出,如果是内存泄露,那么进一步通过工具查看泄露对象到GC Roots的引用链,找到泄露代码的位置;如果是内存溢出,那么可以在物体机器中调大堆参数(-Xmx和-Xms),也需要检查代码中是否存在某些对象生命期过长、持有状态时间过程的情况,尝试减少程序运行期的内存消耗
2、虚拟机栈和本地方法栈溢出
虚拟机栈和本地方法栈溢出原因可能有以下两种:StackOverflowError异常和OutOfMemory异常
注:在单线程条件下,无论是请求的栈深度大于虚拟机所允许的最大深度,还是内存溢出,虚拟机都会抛出StackOverflowError异常,多线程会出现内存溢出异常
故:在多线程导致内存溢出,在不能减少线程数量和更换虚拟机的情况下,只能通过减少最大堆和减少栈容量来换取更多的线程
3、方法区和运行时常量池溢出
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述,所以在产生大量动态类时,方法区就会出现溢出。例如CGLib字节码增强和动态语言以外,还有大量JSP或者动态产生JSP文件的应用和基于OSGI的应用
4、直接内存溢出:略
JVM模型及内存溢出的更多相关文章
- JVM原理及内存溢出
JVM原理及内存溢出
- 【深入Java虚拟机】之一:Java内存模型与内存溢出
[深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...
- jvm中的内存溢出与内存泄露
内存溢出: 就是我们通常遇到的OutOfMemoryError异常,它俗理解就是内存不够,通常在运行大型程序时发生,当程序所需要的内存远远超出了JVM内存所承受大小,就会报出OutOfMemoryEr ...
- JVM探秘:内存溢出
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 在 Java 虚拟机内存区域中,除了程序计数器外,其他几个内存区域都可能会发生OutO ...
- JVM(2) Java内存溢出异常
在Java虚拟机运行时数据区中,除了程序计数器之外,虚拟机栈.本地方法栈.方法区和Java堆都有发生OutOfMemoryError(简称OOM)异常的可能. 一.Java堆溢出 Java堆用于存储对 ...
- JVM 中发生内存溢出的 8 种原因及解决办法
1. Java 堆空间 2. GC 开销超过限制 3. 请求的数组大小超过虚拟机限制 4. Perm gen 空间 5. Metaspace 6. 无法新建本机线程 7. 杀死进程或子进程 8. 发生 ...
- 深入理解jvm之内存区域与内存溢出
文章目录 1. Java内存区域与内存溢出异常 1.1. 运行时数据区域 1.1.1. 程序计数器 1.1.2. java虚拟机栈 1.1.3. 本地方法栈 1.1.4. Java堆(Java Hea ...
- JVM探秘2--详解内存溢出OutOfMemoryError异常
JVM运行时内存被划分成多个区域,而除了程序计数器之外,其他几个区都会出现OutOfMemoryError异常,主要原因就是对应内存区域的内存不足以再分配内存,一般要么是内存泄漏了要么就是内存参数设置 ...
- BAT面试必问题系列:深入详解JVM 内存区域及内存溢出分析
前言 在JVM的管控下,Java程序员不再需要管理内存的分配与释放,这和在C和C++的世界是完全不一样的.所以,在JVM的帮助下,Java程序员很少会关注内存泄露和内存溢出的问题.但是,一旦JVM发生 ...
随机推荐
- 【原创】大叔经验分享(79)mysql内存设置
mysql内存设置,首先要知道当前的设置 MySQL [(none)]> show variables like '%buffer%'; +--------------------------- ...
- Git详细操作
Git详细操作 一.本地配置 1公钥钥配置 1.参考帮助文档:https://gitee.com/help/ 仓库管理 =公钥管理 =生成/添加SSH公钥 ssh-keygen -t rsa -C & ...
- linux grep/awk/cut/egrep/echo/经验
1. 例子 http://www.test.com/atk/pki/test-1.1.tar.gz 过滤出test-1.1.tar.gz t = http://www.test.com/atk/pki ...
- 个人学习HTML以及CSS所得体会
拥有自己样式的浏览器: 苹果,欧朋,谷歌,IE,火狐 form标签<form></form> 表单属性: 1,action主要同来规定表单的作用,提交到处理器上面处理URL,默 ...
- 关于dataset
举个栗子: <div id="cost" data-drink="coffee" data-food="sushi" data-mea ...
- SQL学习——SELECT INTO和INSERT INTO SELECT
原文链接 SELECT INTO 作用 SELECT INTO 语句从一个表中复制数据,然后将数据插入到另一个新表中. SELECT INTO 语法 我们可以把所有的列都复制到新表中: SELECT ...
- SpringBoot定时任务(schedule、quartz)
Scheduled 只适合处理简单的计划任务,不能处理分布式计划任务.优势:是spring框架提供的计划任务,开发简单,执行效率比较高.且在计划任务数量太多的时候,可能出现阻塞,崩溃,延迟启动等问题. ...
- 自己整理的的数据操作DbHelper
using System.Data; using System.Data.SqlClient; using System.Configuration; namespace WindowsFormsAp ...
- Golang等待一组协程结束
1. 利用waitgroup import ( "log" "sync" "sync/atomic" "time" ) ...
- 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)
P2746 [USACO5.3]校园网Network of Schools https://www.luogu.org/problem/P2746 题目描述 一些学校连入一个电脑网络.那些学校已订立了 ...