测试OOM异常

转载自    测试OOM异常

一、Java堆溢出

内存溢出和内存泄露

内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用

package com.weixuan.outofmemory;  import java.util.ArrayList;  
import java.util.List;  /** * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 * -XX:+HeapDumpOnOutOfMemoryError *  * @author Nicholas * Java堆溢出 * Java 堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象 * 那么当对象数量到达最大堆的容量限制后就会产生内存溢出异常 */  /* * -Xms20M : 堆的最小值为20m * -Xmx20M : 堆的最大值为20m,最大值和最小值相同,可以避免堆自动扩展 * -Xmn10M : 新生代大小为10m * -XX:+PrintGCDetails : 打印辅助信息 * -XX:SurvivorRatio=8 : Java 堆中的Eden区与Survivor区的大小比值,设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 * -XX:+HeapDumpOnOutOfMemoryError : 当出现内存溢出异常时,dump出当前的内存转储快照信息以便后期分析 */  /** * 如何处理堆内存溢出? * 通过EMA eclipse memory analyzer 打开堆内存转储文件 * 首先分清是内存泄露还是内存溢出 * 如果是内存泄露:通过工具查看泄露对象到GC Roots的引用链,然后找出泄露对象是通过怎样的路径与GC roots 相关联并导致垃圾回收器无法自动回收他们的 * 如果不存在泄露,也就是说内存中的对象还活着,那就应当检查虚拟机的堆参数 -Xmx -Xms 是否可以适当的调整 * */  
public class HeapOOM {  static class OOMObject {  }  public static void main(String[] args) {  List<OOMObject> list = new ArrayList<HeapOOM.OOMObject>();  while (true) {  list.add(new OOMObject());  }  }  
}  

二、虚拟机栈和本地方法栈溢出

package com.weixuan.outofmemory;  /** * 虚拟机栈和本地方法栈溢出 * -Xss128k * @author Nicholas *  在hotspot虚拟机中不区分虚拟机栈和本地方法栈 也就是说 -Xoss参数无效 *  栈容量只由 -Xss参数设置 * *在单线程情况下,无论是栈帧太大还是虚拟机容量太小,当内存无法分配的时候,都是stackoverflowerror异常 */  public class JavaVMStackSOF {  private int stacklength = 1;  public void stackLeak() {  stacklength++;  stackLeak();  }  public static void main(String[] args) {  JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();  try {  javaVMStackSOF.stackLeak();  } catch (Throwable e) {  System.out.println("Stack length : " + javaVMStackSOF.stacklength);  throw e;  }  }  
}  

三、方法区和运行时常量池溢出

package com.weixuan.outofmemory;  import java.util.ArrayList;  
import java.util.List;  /** * 运行时常量池的内存溢出 * -XX:PermSize=10M -XX:MaxPermSize=10M * @author Nicholas * Java 8 已经将永久代从方法区移除 */  /** * intern() 是一个native 方法 *  如果字符串常量池中已经包含一个等于此string对象的字符串,则返回次string对象的引用 */  
public class RuntimeConstantPoolOOM {  public void testIntern() {  String string1 = new StringBuilder("计算机").append("软件").toString();  System.out.println(string1==string1.intern());  String string2 = new StringBuilder("ja").append("va").toString();  System.out.println(string2==string2.intern());  }  public static void main(String[] args) {  List<String> list = new ArrayList<String>();  int i = 0;  while (true) {  list.add(String.valueOf(i++).intern());  }  }  
}  
Java 8 已经将永久代从方法区移除

四、本机直接内存溢出

package com.weixuan.outofmemory;  import java.lang.reflect.Field;  import sun.misc.Unsafe;  /** * -Xms20M -XX:MaxDirectMemorySize=10M * @author Nicholas * */  
public class DirectMemoryOOM {  private static final int _1MB = 1024 * 1024;  public static void main(String[] args) {  // TODO Auto-generated method stub  Field unsafeField = Unsafe.class.getDeclaredFields()[0];  unsafeField.setAccessible(true);  Unsafe unsafe = null;  try {  unsafe = (Unsafe) unsafeField.get(null);  } catch (IllegalArgumentException | IllegalAccessException e) {  e.printStackTrace();  }  while (true) {  unsafe.allocateMemory(_1MB);  }  }  }  

五、总结

内存泄露的几种场景:

1、长生命周期的对象持有短生命周期对象的引用

这是内存泄露最常见的场景,也是代码设计中经常出现的问题。

例如:在全局静态map中缓存局部变量,且没有清空操作,随着时间的推移,这个map会越来越大,造成内存泄露。

2、修改hashset中对象的参数值,且参数是计算哈希值的字段

当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段,否则对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中删除当前对象,造成内存泄露。

3、机器的连接数和关闭时间设置

长时间开启非常耗费资源的连接,也会造成内存泄露。

内存溢出的几种情况:

1、堆内存溢出(outOfMemoryError:java heap space)

在jvm规范中,堆中的内存是用来生成对象实例和数组的。

如果细分,堆内存还可以分为年轻代和年老代,年轻代包括一个eden区和两个survivor区。

当生成新对象时,内存的申请过程如下:

a、jvm先尝试在eden区分配新建对象所需的内存;

b、如果内存大小足够,申请结束,否则下一步;

c、jvm启动youngGC,试图将eden区中不活跃的对象释放掉,释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;

d、Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;

e、 当OLD区空间不够时,JVM会在OLD区进行full GC;

f、full GC后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”:

outOfMemoryError:java heap space

2、方法区内存溢出(outOfMemoryError:permgem space)

在jvm规范中,方法区主要存放的是类信息、常量、静态变量等。

所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出,一般该区发生内存溢出时的错误信息为:

outOfMemoryError:permgem space

3、线程栈溢出(java.lang.StackOverflowError)

线程栈时线程独有的一块内存结构,所以线程栈发生问题必定是某个线程运行时产生的错误。

一般线程栈溢出是由于递归太深或方法调用层级过多导致的。

发生栈溢出的错误信息为:

java.lang.StackOverflowError

如何避免内存泄露

1、尽早释放无用对象的引用

2、使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域

3、尽量少用静态变量,因为静态变量存放在永久代(方法区),永久代基本不参与垃圾回收

4、避免在循环中创建对象

5、开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。


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

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

相关文章

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

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

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

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

java实现打印倒直角三角形

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

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

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

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

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

使用Dom4j解析XML

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

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

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

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

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

中南大学计算机网.doc,中南大学计算机网络实验报告.doc

计算机网络实验报告0909122820周建权第第 PAGE \* MERGEFORMAT 1 页 共 NUMPAGES \* MERGEFORMAT 11 页计算机网络实验报告专业班级&#xff1a;信安1202班指导老师&#xff1a;王伟平姓 名&#xff1a;周建权学 号&#xff1a;0909122820实验二 网络路由层协议模拟实验网络路由…

Java实现HTML代码生成PDF文档

转载自 Java实现HTML代码生成PDF文档1、IText实现html2pdf&#xff0c;速度快&#xff0c;纠错能力差&#xff0c;支持中文&#xff08;要求HTML使用unicode编码&#xff09;&#xff0c;但中支持一种中文字体&#xff0c;开源。 2、Flying Sauser实现html2pdf&#xff0c;纠…

java实现九九乘法表的输出

package cn.jbit.nestedloops; /*** 打印九九乘法表*/ public class MulTable {public static void main(String[] args) {int rows 9; //乘法表的行数for(int i 1; i<rows; i){ //一共9行for(int j 1; j < i; j){ //第i行有i个式子System.out.print(j"*&q…

成人教育计算机统考分数查询江苏省,江苏省教育考试院查询

阅读本文前&#xff0c;请您先点击上面的蓝色字体&#xff0c;再点击“关注”&#xff0c;这样您就可以继续免费收到最新文章了。每天都有分享。完全是免费订阅&#xff0c;请放心关注。注&#xff1a;本文转载自网络&#xff0c;不代表本平台立场&#xff0c;仅供读者参考&…

分布式系统事务一致性解决方案大对比,谁最好使?

“ 在分布式系统中&#xff0c;同时满足“一致性”、“可用性”和“分区容错性”三者是不可能的。分布式系统的事务一致性是一个技术难题&#xff0c;各种解决方案孰优孰劣&#xff1f; 老司机介绍 丁浪&#xff0c;现就职于某垂直电商平台&#xff0c;担任技术架构师。关注高并…

使用Java将HTML转成Word格式文件

转载自 使用Java将HTML转成Word格式文件 import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException;import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.Docum…