一、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模型及内存溢出的更多相关文章

  1. JVM原理及内存溢出

    JVM原理及内存溢出

  2. 【深入Java虚拟机】之一:Java内存模型与内存溢出

    [深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...

  3. jvm中的内存溢出与内存泄露

    内存溢出: 就是我们通常遇到的OutOfMemoryError异常,它俗理解就是内存不够,通常在运行大型程序时发生,当程序所需要的内存远远超出了JVM内存所承受大小,就会报出OutOfMemoryEr ...

  4. JVM探秘:内存溢出

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 在 Java 虚拟机内存区域中,除了程序计数器外,其他几个内存区域都可能会发生OutO ...

  5. JVM(2) Java内存溢出异常

    在Java虚拟机运行时数据区中,除了程序计数器之外,虚拟机栈.本地方法栈.方法区和Java堆都有发生OutOfMemoryError(简称OOM)异常的可能. 一.Java堆溢出 Java堆用于存储对 ...

  6. JVM 中发生内存溢出的 8 种原因及解决办法

    1. Java 堆空间 2. GC 开销超过限制 3. 请求的数组大小超过虚拟机限制 4. Perm gen 空间 5. Metaspace 6. 无法新建本机线程 7. 杀死进程或子进程 8. 发生 ...

  7. 深入理解jvm之内存区域与内存溢出

    文章目录 1. Java内存区域与内存溢出异常 1.1. 运行时数据区域 1.1.1. 程序计数器 1.1.2. java虚拟机栈 1.1.3. 本地方法栈 1.1.4. Java堆(Java Hea ...

  8. JVM探秘2--详解内存溢出OutOfMemoryError异常

    JVM运行时内存被划分成多个区域,而除了程序计数器之外,其他几个区都会出现OutOfMemoryError异常,主要原因就是对应内存区域的内存不足以再分配内存,一般要么是内存泄漏了要么就是内存参数设置 ...

  9. BAT面试必问题系列:深入详解JVM 内存区域及内存溢出分析

    前言 在JVM的管控下,Java程序员不再需要管理内存的分配与释放,这和在C和C++的世界是完全不一样的.所以,在JVM的帮助下,Java程序员很少会关注内存泄露和内存溢出的问题.但是,一旦JVM发生 ...

随机推荐

  1. DIP常用资源整理

    Deep Learning(深度学习): ufldl的2个教程(这个没得说,入门绝对的好教程,Ng的,逻辑清晰有练习):一 ufldl的2个教程(这个没得说,入门绝对的好教程,Ng的,逻辑清晰有练习) ...

  2. JDK + Tomcat 安装 + 制作自定义镜像【第 1 篇 JDK】

    [第 1 篇 JDK]:https://www.cnblogs.com/del88/p/11842387.html[第 2 篇 Tomcat]:https://www.cnblogs.com/del8 ...

  3. php实现拼图滑块验证的思考及部分实现

    实现拼图滑块验证,我觉得其中比较关键的一点就是裁剪图片,最起码需要裁剪出下面两张图的样子 底图 滑块图 一张底图和一张滑块图,其中底图实现起来比较简单可以使用添加水印的方式直接将一张拼图形状的半透明图 ...

  4. html与css注意事项及小知识点

    html 常用的html特殊符号: 空格:&npsd: 版权所有符号:&copy: 注册商标符号:&reg: 有两个标签容器:<span>和<div> ...

  5. 面试之HTML5 Web存储

    前几天面试遇到了一个题是问localStorage和sessionStorage的区别,当时的回答不是很全面,今天就针对这个问题做一下整理(概念,用法,区别) HTML5 Web存储,一个比 cook ...

  6. sql 创建新表时的完成格式

    1 create table [dbo].[Customer] ( CustomerID int identity(1,1) not null, [Name] [nvarchar](50) null, ...

  7. C++ STL 之 string

    #include <iostream> #include <string> using namespace std; // 初始化 void test01() { string ...

  8. Navicat for MySQL 设置定时任务(事件)

    1.查询界面输入命令,查看定时任务是否开启,未开始时OFF: show variables like '%event_scheduler%'; 2. 查询界面输入命令,开启定时任务: set glob ...

  9. Paper Reading:Deep Neural Networks for Object Detection

    发表时间:2013 发表作者:(Google)Szegedy C, Toshev A, Erhan D 发表刊物/会议:Advances in Neural Information Processin ...

  10. PHP 提取数组中奇数或偶数的元素array_filter

    //提取奇数 $filter = array_filter($ql,function($var){ return($var & 1); },ARRAY_FILTER_USE_KEY); pri ...