ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Exception、Error 报错整理

2021-11-11 11:02:14  阅读:179  来源: 互联网

标签:lang Exception java 报错 内存 Error OutOfMemoryError GC public


报错整理

一、堆内存溢出异常 java.lang.OutOfMemoryError: PermGen space

发生原因及问题复现

使用Tomcat 6 启动项目,控制台报错
在这里插入图片描述
在这里插入图片描述

问题分析

Tomcat 6 经过查询,此问题是堆内存不足,调整JVM参数即可解决。

PermGen(永久代)的默认尺寸比较小,64M,进行大量操作变量时,会经常发生

解决原因

项目启动时设置合适JVM参数
-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m

避免发生

根据项目及自己的判断进行设置合适的JVM参数在进行启动。
-Xms1024m 初始
-Xmx1024m
-XX:PermSize=512m
-XX:MaxPermSize=512m

二、并发修改异常 java.util.ConcurrentModificationException

发生原因及问题复现

在这里插入图片描述

问题分析

使用ArrayList 在多线程环境下,大量进行add 操作,会造成并发修改异常

解决原因

List<String> list = new ArrayList<>();

可替换为

List<String> list2 = new Vector<>(); 
List<String> list3 = Collections.synchronizedList(new ArrayList<>());
List<String> list4 = new CopyOnWriteArrayList();

避免发生

当项目中使用大量线程List时,考虑其他几种List

三、栈溢出 java.lang.StackOverflowError

设置 VM参数
-Xms1m -Xmx1m

故障现象
java.lang.StackOverflowError
在这里插入图片描述

导致原因
深度方法调用

package com.xin;

/**
 * @author :小心仔
 * @date :Created in 2021/11/6 21:33
 * @description:
 */
public class StackOverFlowError {
    public static void main(String[] args) {
        StackOverFlowErrors();
    }

    public static void StackOverFlowErrors(){
        StackOverFlowErrors();
    }
}

四、堆内存溢出异常 java.lang.OutOfMemoryError: Java heap space

设置 VM参数
-Xms1m -Xmx1m

故障现象
java.lang.OutOfMemoryError: Java heap space
在这里插入图片描述

导致原因
Java 8,对象太多了,太大

public class JavaHeapSpaceDemo {
    public static void main(String[] args) {
        String str = "1111";
        while (true){
            str += str + new Random().nextInt(1111111) + new Random().nextInt(1111111222);
            str.intern();
        }
    }
}

五、GC回收时间过长异常 java.lang.OutOfMemoryError: GC overhead limit exceeded

配置参数
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m

故障现象
java.lang.OutOfMemoryError: GC overhead limit exceeded
在这里插入图片描述

导致原因
GC 回收时间过长会抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded,超过98%的时间用于GC且回收不到2%的堆内存,加入不抛出异常,会导致内存每次快速填满,导致CPU 一直100%,而GC没有任何成果

public class GCOverHeadDemo {
    public static void main(String[] args) {
        int i = 0;
        List<String> list = new ArrayList<>();
        try {
            while (true) {
                list.add(String.valueOf(++i).intern());
            }
        }catch (Throwable e){
            System.out.println("*****************" + i);
            e.printStackTrace();
            throw e;
        }
    }
}

六、直接内存溢出 java.lang.OutOfMemoryError: Direct buffer memory

配置参数
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m

故障现象
Exception in thread “main” java.lang.OutOfMemoryError: Direct buffer memory
在这里插入图片描述

导致原因
写NIO程序 ,通过Buffe读取和写入数据,这是一种基于 通道(Chanel)与缓冲区(Buffer)的 I / O方式
它可以使用native函数直接分配堆外内存,通过一个存储在 Java堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作,
这样能在一些场景中提高性能,因此避免Java堆和Native堆中来回复制数据。
ByteBuffer.allocate(capability) 第一种方式分配JVM堆内存,属于GC管辖范围,由于需要拷贝比较慢
ByteBuffer.allocateDirect(capability) 第一种方式分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝相对较快
但如果不断分配本地内存,堆内存很少使用,那么JVM不需要执行GC,DirectByteBuffer对象就不会回收
这时候堆内存充足,但本地内存已经用光,再次尝试分配本地内存就会出现OutOfMemoryError,程序崩溃。

public class DirectBufferMemoryDemo {
    public static void main(String[] args) {
        System.out.println("配置的maxDirectMemory" + (sun.misc.VM.maxDirectMemory() /(double) 1024 / 1024) +"MB" );
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace();}
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
    }
}

七、java.lang.OutOfMemoryError: Direct buffer memory

配置参数

故障现象
java.lang.OutOfMemoryError: Direct buffer memory

导致原因
高并发请求服务器时,经常出现与服务器有关
1 你的应用创建太多线程了,一个应用创建多个线程,超过系统承载极限
2 你的服务器不允许应用程序创建折磨多线程,Linux系统默认单个线程可创建线程
你的应用创建超过这个数量,就会报

解决办法
1 想办法降低应用程序创建线程的数量,分析应用是否需要创建折磨多线程,不是,修改代码
2 对于有的应用,确实需要创建很多线程,远超过Linux 默认1024个线程的限制,可修改Linux配置

Linux

 vim /etc/security/limits.d/90-nproc.conf

可以根据实际情况配置

在这里插入图片描述

package com.xin;

import java.util.concurrent.TimeUnit;

/**
 * @author :小心仔
 * @date :Created in 2021/11/7 9:55
 * @description:
 */
public class UnableCreateNewThreadDemo {

    public static void main(String[] args) {
        for (int i = 0; ; i++) {
            System.out.println("****************" + i);
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }

}

八、元空间异常 java.lang.OutOfMemoryError: Metaspace

配置参数
-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m

故障现象
java.lang.OutOfMemoryError: Metaspace
在这里插入图片描述

导致原因
Java8及之后的版本使用Metaspace来替换永久代
Metaspace是在HotSpot中的实现,与持久代的区别在于:Metaspace并不在虚拟机内存中二是使用本地内存,也即是在java8中,class metadata(the virtual machines internal presentation of java class),被存储在叫做Metaspace 的native memory

永久代(Java8之后被原空间Metaspace取代了)存放以下信息:
虚拟机加载的类信息
常量池
静态变量
即时编译后的代码

package com.xin;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author :小心仔
 * @date :Created in 2021/11/7 10:42
 * @description:
 */
public class MetaspaceDemo {

    static class OOMTest{}

    public static void main(String[] args) {
        int i = 0;
        try{
            while (true){
                i++;
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(OOMTest.class);
                enhancer.setUseCache(false);
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        return methodProxy.invokeSuper(o,args);
                    }
                });
                enhancer.create();
            }
        }catch (Throwable t){
            System.out.println(i+"次发生了异常");
            t.printStackTrace();

        }

    }

}

标签:lang,Exception,java,报错,内存,Error,OutOfMemoryError,GC,public
来源: https://blog.csdn.net/weixin_45395031/article/details/121135021

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有