iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java内存溢出的处理方法是什么
  • 386
分享到

Java内存溢出的处理方法是什么

2023-07-04 14:07:08 386人浏览 八月长安
摘要

这篇文章主要介绍“Java内存溢出的处理方法是什么”,在日常操作中,相信很多人在Java内存溢出的处理方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存溢出的处理方法是什么”的疑惑有所帮助!

这篇文章主要介绍“Java内存溢出的处理方法是什么”,在日常操作中,相信很多人在Java内存溢出的处理方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存溢出的处理方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    1、Java堆溢出

    Java堆用于储存对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常。

    1、案例创建

    需要手动调节JVM参数,不然需要等很长时间:-Xms20m -Xmx20m

     public class JavaHeapDemo {      static class OOMObject {      }     public static void main(String[] args) {         List<OOMObject> list = new ArrayList<OOMObject>();         //利用while循环不断创建对象         while (true) {             list.add(new OOMObject());         }     } }

    Java内存溢出的处理方法是什么

    2、处理方法

    常规的处理方法是首先通过内存映像分析工具(如Eclipse Memory Analyzer)对Dump出来的堆转储快照进行分析

    1. 分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)

    2. 内存泄漏:通过工具查看泄漏对象到GC Roots的引用链,找到泄漏对象是通过怎样的引用路径、与哪些GC Roots相关联,才导致垃圾收集器无法回收它们,根据泄漏对象的类型信息以及它到GC Roots引用链的信息,一般可以比较准确地定位到这些对象创建的位置,进而找出产生内存泄漏的代码的具体位置

    3. 内存溢出:检查Java虚拟机的堆参数(-Xmx与-Xms)设置,与机器的内存对比,看看是否还有向上调整的空间。再从代码上检查 是否存在某些对象生命周期过长、持有状态时间过长、存储结构设计不合理等情况,尽量减少程序运行期的内存消耗

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

    关于虚拟机栈和本地方法栈,在《Java虚拟机规范》中描述了两种异常:

    • 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

    • 如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出OutOfMemoryError异常

    《Java虚拟机规范》明确允许Java虚拟机实现自行选择是否支持栈的动态扩展,而HotSpot虚拟机的选择是不支持扩展,所以除非在创建

    线程申请内存时就因无法获得足够内存而出现OutOfMemoryError异常,否则在线程运行时是不会因为扩展而导致内存溢出的,只会因为

    栈容量无法容纳新的栈帧而导致StackOverflowError异常

    1、使用-Xss参数减少栈内存容量

     public class JavaVMStackSOF {      private int stackLength = 1;      public void stackLength() {         stackLength++;         //无限递归         stackLength();     }      public static void main(String[] args) {         JavaVMStackSOF sof = new JavaVMStackSOF();         try {             sof.stackLength();         } catch (Throwable e) {             System.out.println("stack length:" + sof.stackLength);             throw e;         }     } }

    这里可以通过指定参数-Xss128k,用来测试栈溢出的情况

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

    HotSpot从jdk 7开始逐步“去永久代”的计划,并在JDK 8中完全使用元空间来代替永久代的背景故事,使用“永久代”还是“元空间”来

    实现方法区,对程序有什么实际的影响。

    String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的

    String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。

    这里测试需要JDK6:-XX:PermSize=6M -XX:MaxPermSize=6M

     public class RuntimeConstantPoolOOM {      public static void main(String[] args) {         // 使用Set保持着常量池引用,避免Full GC回收常量池行为         Set<String> set = new HashSet<String>();         // 在short范围内足以让6MB的PermSize产生OOM了         short i = 0;         while (true) {             set.add(String.valueOf(i++).intern());         }     } }

    JDK8模拟测试

     package jdk8;  import java.io.File; import java.lang.management.ClassLoadingMXBean; import java.lang.management.ManagementFactory; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List;   public class OOMTest {     public static void main(String[] args) {         try {             //准备url             URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL();             URL[] urls = {url};             //获取有关类型加载的JMX接口             ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();             //用于缓存类加载器             List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();             while (true) {                 //加载类型并缓存类加载器实例                 ClassLoader classLoader = new URLClassLoader(urls);                 classLoaders.add(classLoader);                 classLoader.loadClass("ClassA");                 //显示数量信息(共加载过的类型数目,当前还有效的类型数目,已经被卸载的类型数目)                 System.out.println("total: " + loadingBean.getTotalLoadedClassCount());                 System.out.println("active: " + loadingBean.getLoadedClassCount());                 System.out.println("unloaded: " + loadingBean.getUnloadedClassCount());             }         } catch (Exception e) {             e.printStackTrace();         }     } }

    方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,要达成的条件是比较苛刻的。在经常运行时生成大量动态类的应用场景里,就应该特别关注这些类的回收状况。这类场景除了之前提到的程序使用了CGLib字节码增强和动态语言外,常见的还有:大量jsP或动态产生JSP文件的应用(JSP第一次运行时需要编译为Java类)、基于OSGi的应用(即使是同一个类文件,被不同的加载器加载也会视为不同的类)等。

    在JDK 8以后,永久代便完全退出了历史舞台,元空间作为其替代者登场。在默认设置下,前面列举的那些正常的动态创建新类型的测试用例已经很难再迫使虚拟机产生方法区的溢出异常了。不过为了让使用者有预防实际应用里出现类似于代码清单2-9那样的破坏性的操作,HotSpot还是提供了一些参数作为元空间的防御措施,主要包括:

    • -XX:MaxMetaspaceSize:设置元空间最大值,默认是-1,即不限制,或者说只受限于本地内存大小。

    • -XX:MetaspaceSize:指定元空间的初始空间大小,以字节为单位,达到该值就会触发垃圾收集进行类型卸载,同时收集器会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过-XX:MaxMetaspaceSize(如果设置了的话)的情况下,适当提高该值。

    • -XX:MinMetaspaceFreeRatio:作用是在垃圾收集之后控制最小的元空间剩余容量的百分比,可减少因为元空间不足导致的垃圾收集的频率。类似的还有-XX:Max-MetaspaceFreeRatio,用于控制最大的元空间剩余容量的百分比。

    4、本机直接内存溢出

    直接内存(Direct Memory)的容量大小可通过-XX:MaxDirectMemorySize参数来指定,如果不去指定,则默认与Java堆最大值(由-Xmx指定)一致。

    JVM参数:-Xmx20M -XX:MaxDirectMemorySize=10M

     public class DirectMemoryOOM {     private static final int _1MB = 1024 * 1024;          public static void main(String[] args) throws Exception {         Field unsafeField = Unsafe.class.getDeclaredFields()[0];         unsafeField.setAccessible(true);         Unsafe unsafe = (Unsafe) unsafeField.get(null);         while (true) {             unsafe.allocateMemory(_1MB);         }     } }

    Java内存溢出的处理方法是什么

    越过了DirectByteBuffer类直接通过反射获取Unsafe实例进行内存分配(Unsafe类的getUnsafe()方法指定只有引导类加载器才会返回实例,体现了设计者希望只有虚拟机标准类库里面的类才能使用Unsafe的功能,在JDK 10时才将Unsafe的部分功能通过VarHandle开放给外部使用),因为虽然使用DirectByteBuffer分配内存也会抛出内存溢出异常,但它抛出异常时并没有真正向操作系统申请分配内存,而是通过计算得知内存无法分配就会在代码里手动抛出溢出异常,真正申请分配内存的方法是Unsafe::allocateMemory()。

    到此,关于“Java内存溢出的处理方法是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: Java内存溢出的处理方法是什么

    本文链接: https://www.lsjlt.com/news/345635.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Java内存溢出的处理方法是什么
      这篇文章主要介绍“Java内存溢出的处理方法是什么”,在日常操作中,相信很多人在Java内存溢出的处理方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java内存溢出的处理方法是什么”的疑惑有所帮助!...
      99+
      2023-07-04
    • java内存溢出排查的方法是什么
      排查Java内存溢出问题的一般方法如下:1. 定位溢出位置:首先需要确定内存溢出的位置,可以通过查看错误日志或者使用内存分析工具来定...
      99+
      2023-10-10
      java
    • Tomcat内存溢出及内存设置的方法是什么
      今天小编给大家分享一下Tomcat内存溢出及内存设置的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。java的内存...
      99+
      2023-06-26
    • spark防止内存溢出的方法是什么
      Spark防止内存溢出的方法包括: 调整内存分配:可以通过调整Spark的executor内存大小、driver内存大小以及每个...
      99+
      2024-04-02
    • java中内存泄漏和内存溢出是什么
      内存泄漏(Memory Leak)是指在程序运行过程中,因为不正确的内存管理而导致一部分内存无法被回收的现象。当程序中的对象不再被使...
      99+
      2023-08-25
      java
    • java内存泄漏和内存溢出的原因是什么
      Java内存泄漏和内存溢出的原因如下:1. 内存泄漏:内存泄漏指的是在程序运行过程中,无用的对象仍然被保持在内存中,导致内存占用不断...
      99+
      2023-08-26
      java
    • java内存溢出的四种情况是什么
      这篇文章主要介绍了java内存溢出的四种情况是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java内存溢出的四种情况是什么文章都会有所收获,下面我们一起来看看吧。1、堆溢出,堆是存放实例对象的,但是这样堆...
      99+
      2023-06-30
    • java内存溢出的原因和解决办法是什么
      Java内存溢出的原因通常是程序申请的内存超过了JVM所能提供的内存限制。常见的内存溢出原因包括:1. 对象创建过多:如果程序中频繁...
      99+
      2023-08-18
      java
    • jvm内存溢出如何处理
      JVM内存溢出是指在Java虚拟机执行程序时,无法分配到足够的内存空间,导致程序异常终止。处理JVM内存溢出的方法有以下几种:1. ...
      99+
      2023-08-11
      jvm
    • kafka内存溢出如何处理
      Kafka内存溢出可以通过以下几种方式进行处理: 增加Kafka的堆内存:可以通过调整Kafka的JVM参数,增加堆内存大小,例...
      99+
      2023-10-27
      kafka
    • JavaScript内存泄漏和内存溢出是什么
      本篇内容主要讲解“JavaScript内存泄漏和内存溢出是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript内存泄漏和内存溢出是什么”吧! ...
      99+
      2024-04-02
    • Java中内存泄露与溢出的区别是什么
      这期内容当中小编将会给大家带来有关Java中内存泄露与溢出的区别是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java内存泄露与溢出的区别内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足...
      99+
      2023-06-17
    • jvm内存溢出排查的步骤是什么
      排查JVM内存溢出的步骤可以分为以下几个步骤:1. 确认内存溢出问题:通过观察应用程序的行为和报错信息,确认是否存在内存溢出问题。2...
      99+
      2023-08-11
      jvm
    • 怎么在java中排查内存是否溢出
      怎么在java中排查内存是否溢出?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端...
      99+
      2023-06-14
    • PHP内存溢出的解决方法详解
      目录1.处理数组时出现内存溢出2.使用sql查询数据,查出来很多,导致内存溢出3.假定日志中存放的记录数为500000条,那么解决方案如下4.上传excel文件时,出现内存溢出的情况...
      99+
      2024-04-02
    • 记一次JVM内存溢出的处理过程
      概要笔者所管理的测试一台业务服务器,近期经常被反馈应用卡顿并且出现过多次内存溢出,本篇为对此问题的处理过程的记录。服务器环境采用Oracle JDK1.6,虚拟机为HosSpot,Web容器为Tomcat7。处理过程获取堆内存转储快照在用户...
      99+
      2023-06-02
    • java内存管理与内存溢出异常的示例分析
      这篇文章主要介绍了java内存管理与内存溢出异常的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。说到内存管理,笔者这里想先比较一下java与C、C++之间的区别:在C...
      99+
      2023-05-31
      java
    • 如何理解Java中的内存溢出问题
      这篇文章主要介绍“如何理解Java中的内存溢出问题”,在日常操作中,相信很多人在如何理解Java中的内存溢出问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Java中的内存溢出问题”的疑惑有所帮助!...
      99+
      2023-06-15
    • css3溢出隐藏的方法是什么
      这篇文章给大家介绍css3溢出隐藏的方法是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度widt...
      99+
      2023-06-22
    • 详解ThreadLocal为什么会内存溢出原理
      目录前言ThreadLocal源码分析ThreadLocal value内存溢出总结前言 关于ThreadLocal (线程本地存储),从字面意思上看主要是存储一些本地变量,使它们...
      99+
      2023-01-04
      ThreadLocal内存溢出 ThreadLocal内存
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作