深入JVM——OOM异常解析

转载自  深入JVM——OOM异常解析

JVM对象访问解析

对象访问过程的内存情况

public void function(){Object obj = new Object();
}
?

function方法被执行的时候,JVM在JVM栈中为function创建一个栈帧,用于存放function在运行过程中的一些信息。
Object obj被执行时,JVM在function方法对应的栈帧中的本地变量表中创建Object类型的引用obj。
new Object()被执行时,JVM在堆内存中创建一块Object类型的、包含实例数据值的结构化内存。
PS:不同的类型所对应的这块结构化内存的长度是不一样的。

对象访问的方式
不同的虚拟机的对象访问方式有所不同,主流的访问方式有两种:使用句柄间接访问实例数据、指针直接访问实例数据。

a)指针直接访问实例数据
在这种方式中,JVM栈中的栈帧中的本地变量表中所存储的引用地址就是实例数据的地址。通过这个引用就能直接获取到实例数据的地址。
除此之外,其实引用所指向的对内存中的对象数据有两部分组成,一部分就是这个对象实例本身,另一部分是对象类型在方法区中的地址。

b)使用句柄间接访问实例数据
JVM会在堆中划分一块内存来作为句柄池,JVM栈中的栈帧中的本地变量表中所存储的引用地址是这个对象所对应的句柄地址,而非对象本身的地址。句柄池中的一个个对象地址有两部分组成,一部分就是对象数据在堆内存中实例池中的地址,另一部分就是对象类型在方法区中的地址。

综上所述:句柄池就相当于一个中转站,我们要查询的实例对象数据需要通过一次间接索引获取;而指针的直接访问无需中转站,引用指向的就是要访问的实例对象数据。

此外,不管是哪种对象的访问方式,引用所指向的堆内存中的数据都是有两部分组成,其中有一部分一定是一个指向方法区中的对象类型的指针。

两种对象访问方式的好处
a)句柄访问对象的好处
访问对象通过一个句柄指针一次间接索引之后,当对象实例数据被移动的时候(垃圾回收的时候有些对象会被移动),只需要改变句柄池中该对象实例的地址即可,无需改变引用和句柄池的对应关系,所以引用中存储的是稳定的句柄地址。

b)指针直接访问对象的好处
这种方式最大的好处就是访问对象的速度很快,比通过句柄访问对象节约了一半的寻址时间,由于Java中对象的访问非常频繁,所以这种方式能节约很多寻址时间。

OOM异常解析

堆内存的OOM异常
a)如何产生?
堆内存用于存储实例对象,当我们不断创建对象,并且对象都有引用指向(GC Roots到对象之间有可达路径),那么垃圾回收机制就不会清理这些对象,当对象多到挤满堆内存的上限后,就产生OOM异常。

b)模拟堆内存OOM异常
PS:在eclipse的Arguments中可以设置VM arguments,这就是JVM的一些参数。
-Xms:设置堆的最小值
-Xmx:设置堆的最大值

?

public class A(){public static void main(String[] args){while(true){new Person();}}
}
//运行结果中出现:java.lang.OutOFMemory:Java heap space
//说明是在堆内存中发生了OOM异常。
c)如何解决?
使用内存映像分析工具:Eclipse Memory Analyzer对dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,即要搞明白是内存泄漏还是内存溢出。
PS:内存泄漏导致的OOM:new出来的很多对象已经不需要了,但仍然有引用指向,所以垃圾回收机制无法回收。
PS:内存溢出:new出来的对象都是需要的,但堆内存太小装不下了。
如果是内存泄漏,通过工具查看泄漏对象到GC Roots的引用链。找到泄漏对象是通过怎样的路径与GC Roots发生关联,然后导致垃圾回收机制无法自动回收的。
如果不存在内存泄漏,也就是所有的对象都必须存在,这时候就调大堆内存。


JVM栈和本地方法栈的OOM异常

a)StackOverFlowError
当线程请求的栈深度大于虚拟机所允许的最大栈深度,就会抛出这个异常。
b)OutOfMemeoryError
当虚拟机要扩展栈时无法申请到足够空间的内存,就会抛出这个异常。
PS:这两种异常其实是对同一个问题的两种描述。在单一线程下,不论是栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverFlowError。通过测试发现,如果给每个线程的JVM栈分配的内存越大,大的栈帧在这个JVM栈中也能装得下,理应StackOverFlowError会减少,但事实却恰恰相反:当每个线程的JVM栈越大,那么所能创建的线程数就越少,稍微建立几个线程可能就会把有限的内存资源耗尽。

运行时常量池的OOM异常
我们通过String类的intern()方法向方法区中的常量池添加内容。
intern方法的作用是:当常量池中已经有这个String类型所对应的字符串的话,就返回这个字符串的引用;如果常量池中没有这个字符串的话就将这个字符串添加到常量池中,再返回这个字符串的引用。

方法区的OOM异常
a)如何产生?
方法区中存放的是Class的相关信息,如:类名、访问修饰符、常量池、字段描述、方法描述等。
如果产生大量的类就有可能将方法区填满,从而产生方法区的OOM异常。

b)注意点
方法区的OOM异常是非常常见的,特别是在一些动态生成大量Class的应用中(JSP),需要特别注意类的回收。

本机直接内存的OOM异常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mvc html.antiforgerytoken,MVC Html.AntiForgeryToken() 防止CSRF***

MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)***的一个措施,它跟XSS(XSS又叫CSS:Cross-Site-Script),***不同,XSS一般是利用站内信任的用户在网站内插入恶意的脚本代码进行***,而CSRF则是伪造成受信任用户对网站进行***…

使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(一)-- 起步

一、安装Visual Studio Code 安装文件下载地址:VS Code,当前最新版本是1.3。 推荐安装最新版,因为附带Debug插件,支持在vs code上进行断点调试。 二、安装.Net Core 1.0 SDK 安装文件下载地址:.Net Core SDK 三、创建一…

计算机应用基础期中上机考试,期中考试计算机应用基础试卷

中职17计算机1期中考试计算机应用基础试卷一、选择题1.在Excel2010工作簿中,至少应含有的工作表个数是()。A.0B.1C.2D.32.在Excel2010公式中,地址引用E$6是()A.引用绝对地址B.相对地址C.混合地址D.都不是3.在Excel2010默认建立的工作簿中,用户对工作表()。A.可以增加或删除B.不…

java实现打印直角三角形

package cn.jbit.nestedloops; import java.util.Scanner; /*** 输入行数打印直角三角形*/ public class RTriAngle {public static void main(String[] args) {int rows 0; //三角形行数System.out.print("请输入直角三角形的行数:");Scanner input ne…

ASP.NET Core Linux下为 dotnet 创建守护进程(必备知识)

前言 在上篇文章中《ASP.NET Core Docker部署》中介绍了如何在 Docker 容器中部署我们的 asp.net core 应用程序,本篇主要是怎么样为我们在 Linux 或者 macOs 中部署的 dotnet 程序创建一个守护进程,来保证我们的程序在异常或者是电脑重启的时候仍然能够…

测试OOM异常

转载自 测试OOM异常一、Java堆溢出内存溢出和内存泄露内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。内存泄露:指程序中动态分配内…

html为什么未响应,Word2010总是未响应怎么办?

回答:一、自动恢复尚未保存的修改Word提供了“自动恢复”功能,可以帮助用户找回程序遇到问题并停止响应时尚未保存的信息。实际上,在你不得不在没有保存工作成果就重新启动电脑和Word后,系统将打开“文档恢复”任务窗格&#xff0…

Conway#39;s law(康威定律)

Mel Conway 康威在加利福尼亚理工学院获得物理学硕士学位,在凯斯西储大学获得数学博士学位。毕业之后,他参与了很多知名的软件项目,如 Pascal 编辑器。在他的职业生涯中,康威观察到一个现象:软件团队开发的产品是对公…

java实现打印倒直角三角形

package cn.jbit.nestedloops; import java.util.Scanner; /*** 输入行数打印倒直角三角形*/ public class InvertRTriAngle {public static void main(String[] args) {int rows 0; //三角形行数System.out.print("请输入直角三角形的行数:");Scanner i…

使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(二)-- Web Api Demo

在上一篇里,我已经建立了一个简单的Web-Demo应用程序。这一篇将记录将此Demo程序改造成一个Web Api应用程序。 一、添加ASP.NET Core MVC包 1. 在project.json文件添加Microsoft.AspNetCore.Mvc包 { "version": "1.0.0-*", "buildOptions&…

学院派 实践派 计算机科学与技术,饶旻现场为boss所在企业“挑错”

饶旻,高考数学成绩146分,考研数学成绩145分,用数字告诉boss团自己是智商超过140的高才能求职者,16岁就考上中国人民大学计算机科学与技术本科,现在24的饶旻是中国人民大学网络经济学专业博士在读生,上《非你…

使用Dom4j解析XML

转载自 使用Dom4j解析XMLdom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在Sou…

.NET Core扩展IServiceCollection自动注册服务

前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中,通过IServiceCollection接口进行注入即可,其它的无需关心。 通过接口的Add*方法进行注册,代码如下: 1 public void Confi…

微型计算机中被处理信息称为,2011海南省计算机等级考试试题 二级C试题考资料...

1、微型计算机的显示器显示西文字符时,一般情况下一屏最多可显示( A )A、25行,每行80个字符 B、25行,每行60个字符C、20行,每行80个字符 D、20行,每行60个字符2、计算机中,一个浮点数由两部分组成&#xff…

dom4j读取XML文件内容

转载自 dom4j读取XML文件内容<?xml version"1.0" encoding"UTF-8"?> <RESULT> <VALUE><NO>A1234</NO><ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE><NO>B1234</NO><…

我为什么用docker-compose来打包开发环境

BUILD, SHIP, RUNDocker is the world’s leading software containerization platform Docker的出现&#xff0c;让虚拟技术更上一个台阶。更有Docker Hub作为docker images的市场载体&#xff0c;让全世界分享你的成果。 建议使用Docker for Mac(10.10.3) 或 Docker for Wind…

微型计算机使用键盘上的alt键称为,微型计算机使用的键盘上的Alt键称为_____。...

摘要&#xff1a;须牢盒安光缆固、微型装必整齐接头&#xff0c;信线规定《通路工程验范》收规&#xff0c;作伸必须两侧缩(。在交)米越时为(&#xff0c;微型信光)规途通缆线路工定《长程验范》收规。小净火栓光缆米架空距消距为的最&#xff0c;计算机使键盘t键信光)规途通缆…

java使用htmlparser提取网页纯文本例子

转载自 java使用htmlparser提取网页纯文本例子这篇文章主要介绍了java使用htmlparser提取网页纯文本例子,需要的朋友可以参考下package com.test; import org.htmlparser.Node; import org.htmlparser.NodeFilter; import org.htmlparser.Parser; import org.htmlparser.filt…

java实现打印等腰三角形

package cn.jbit.nestedloops; import java.util.Scanner; /*** 输入行数打印等腰三角形*/ public class IsoTriangle {public static void main(String[] args) {int rows 0; //三角形行数System.out.print("请输入等腰三角形的行数&#xff1a;");Scanner input …

在.NET Core中使用MySQL5.7的JSON类型字段

Getting Started ① Adding pomelo myget feed into your NuGet.config which located in your solution root. <?xml version"1.0" encoding"utf-8"?><configuration><packageSources><add key"nuget.org" value"h…