精华内容
下载资源
问答
  • java中三种常见内存溢出错误的处理方法
    2021-02-12 17:20:23

    相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的认识。

    在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Heap space(堆区域)、Java Stacks(Java栈)。其中永久保存区域主要存放Class(类)和Meta的信息,Class第一次被Load的时候被放入PermGen space区域,Class需要存储的内容主要包括方法和静态属性。堆区域用来存放Class的实例(即对象),对象需要存储的内容主要是非静态属性。每次用new创建一个对象实例后,对象实例存储在堆区域中,这部分空间也被jvm的垃圾回收机制管理。而Java栈跟大多数编程语言包括汇编语言的栈功能相似,主要基本类型变量以及方法的输入输出参数。Java程序的每个线程中都有一个独立的堆栈。容易发生内存溢出问题的内存空间包括:Permanent Generation space和Heap space。

    第一种OutOfMemoryError: PermGen space

    发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。解决这类问题有以下两种办法:

    增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m" 如果是windows服务器还可以在系统环境变量中设置。感觉用tomcat发布sprint+struts+hibernate架构的程序时很容易发生这种内存溢出错误。使用上述方法,我成功解决了部署ssh项目的tomcat服务器经常宕机的问题。

    清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重复加载。这种方法是网上部分人推荐的,我没试过,但感觉减少不了太大的空间,最靠谱的还是第一种方法。

    第二种OutOfMemoryError:  Java heap space

    发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。解决这类问题有两种思路:

    检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。 我以前写一个使用K-Means文本聚类算法对几万条文本记录(每条记录的特征向量大约10来个)进行文本聚类时,由于程序细节上有问题,就导致了Java heap space的内存溢出问题,后来通过修改程序得到了解决。

    增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

    第三种OutOfMemoryError:unable to create new native thread

    在java应用中,有时候会出现这样的错误:OutOfMemoryError: unable to create new native thread.这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。

    那么是什么原因造成这种问题呢?

    每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。

    这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。

    给出一个有关能够创建线程的最大个数的估算公式:

    (MaxProcessMemory-JVMMemory-ReservedOsMemory)/(ThreadStackSize)=Numberof threads

    对于jdk1.5而言,假设操作系统保留120M内存:

    1.5GBJVM:(2GB-1.5Gb-120MB)/(1MB)=~380threads

    1.0GBJVM:(2GB-1.0Gb-120MB)/(1MB)=~880threads

    对于栈大小为256KB的jdk1.4而言,

    1.5GBallocated to JVM:~1520threads

    1.0GBallocated to JVM:~3520threads

    对于这个异常我们首先需要判断下,发生内存溢出时进程中到底都有什么样的线程,这些线程是否是应该存在的,是否可以通过优化来降低线程数; 另外一方面默认情况下java为每个线程分配的栈内存大小是1M,通常情况下,这1M的栈内存空间是足足够用了,因为在通常在栈上存放的只是基础类型的数据或者对象的引用,这些东西都不会占据太大的内存, 我们可以通过调整jvm参数,降低为每个线程分配的栈内存大小来解决问题,例如在jvm参数中添加-Xss128k将线程栈内存大小设置为128k。

    更多相关内容
  •  Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。下面详细...
  • 1.JVM Heap(堆)溢出java.lang.OutOfMemoryError: Java heap spaceJVM在启动的时候会自动设置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion...

    1.JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap space

    JVM在启动的时候会自动设置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的时候将抛出此异常信息。

    解决方法:手动设置JVM Heap(堆)的大小。

    Java堆用于储存对象实例。当需要为对象实例分配内存,而堆的内存占用又已经达到-Xmx设置的最大值。将会抛出OutOfMemoryError异常。例子如下:

    packagecom.demo.test;importjava.util.ArrayList;importjava.util.List;/*** VM Args: -Xms5m -Xmx5m*/

    public classHeapOOM {public static voidmain(String[] args) {int count = 0;

    List list = new ArrayList();while(true){

    list.add(newObject());

    System.out.println(++count);

    }

    }

    }

    然后在运行时设置jvm参数,如下:

    710de581f20a3d05ac9990141830f8b0.png

    -Xmx为5m。其中的一次测试结果为,当count的值累加到360145时,发生如下异常:

    Exception in thread "main"java.lang.OutOfMemoryError: Java heap space

    at java.util.Arrays.copyOf(Arrays.java:2245)

    at java.util.Arrays.copyOf(Arrays.java:2219)

    at java.util.ArrayList.grow(ArrayList.java:213)

    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:187)

    at java.util.ArrayList.add(ArrayList.java:411)

    at com.demo.test.HeapOOM.main(HeapOOM.java:12)

    修改-Xmx为10m。其中的一次测试结果为,当count的值累加到540217时,发生OutOfMemoryError异常。随着-Xmx参数值的增大,java堆中可以存储的对象也越多。

    2.PermGen space溢出: java.lang.OutOfMemoryError: PermGen space

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,sun的 GC不会在主程序运行期对PermGen space进行清理,所以如果你的APP会载入很多CLASS的话,就很可能出现PermGen space溢出。一般发生在程序的启动阶段。

    解决方法: 通过-XX:PermSize和-XX:MaxPermSize设置永久代大小即可。

    方法区用于存放java类型的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。在类装载器加载class文件到内存的过程中,虚拟机会提取其中的类型信息,并将这些信息存储到方法区。当需要存储类信息而方法区的内存占用又已经达到-XX:MaxPermSize设置的最大值,将会抛出OutOfMemoryError异常。对于这种情况的测试,基本的思路是运行时产生大量的类去填满方法区,直到溢出。这里需要借助CGLib直接操作字节码运行时,生成了大量的动态类。例子如下:

    packagecom.demo.test;importjava.lang.reflect.Method;importnet.sf.cglib.proxy.Enhancer;importnet.sf.cglib.proxy.MethodProxy;importnet.sf.cglib.proxy.MethodInterceptor;/*** VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M*/

    public classMethodAreaOOM {public static voidmain(String[] args) {int count = 0;while (true) {

    Enhancer enhancer= newEnhancer();

    enhancer.setSuperclass(MethodAreaOOM.class);

    enhancer.setUseCache(false);

    enhancer.setCallback(newMethodInterceptor() {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throwsThrowable {returnproxy.invoke(obj, args);

    }

    });

    enhancer.create();

    System.out.println(++count);

    }

    }

    }

    -XX:MaxPermSize为10m。其中的一次测试结果为,当count的值累加到800时,发生如下异常:

    Caused by: java.lang.OutOfMemoryError: PermGen space

    at java.lang.ClassLoader.defineClass1(Native Method)

    at java.lang.ClassLoader.defineClass(ClassLoader.java:792)

    ...8 more

    随着-XX:MaxPermSize参数值的增大,java方法区中可以存储的类型数据也越多。

    3.栈溢出: java.lang.StackOverflowError : Thread Stack space

    栈溢出了,JVM依然是采用栈式的虚拟机,这个和C和Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了。调用构造函数的 “层”太多了,以致于把栈区溢出了。 通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K的空间(这个大约相当于在一个C函数内声明了256个int类型的变量),那么栈区也不过是需要1MB的空间。通常栈的大小是1-2MB的。通俗一点讲就是单线程的程序需要的内存太大了。 通常递归也不要递归的层次过多,很容易溢出。

    解决方法:1:修改程序。2:通过 -Xss: 来设置每个线程的Stack大小即可。

    在Java虚拟机规范中,对这个区域规定了两种异常状况:StackOverflowError和OutOfMemoryError异常。

    (1)StackOverflowError异常

    每当java程序代码启动一个新线程时,Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。当线程调用java方法时,虚拟机压入一个新的栈帧到该线程的java栈中。只要这个方法还没有返回,它就一直存在。如果线程的方法嵌套调用层次太多(如递归调用),随着java栈中帧的逐渐增多,最终会由于该线程java栈中所有栈帧大小总和大于-Xss设置的值,而产生StackOverflowError内存溢出异常。例子如下:

    packagecom.demo.test;/*** VM Args: -Xss128k*/

    public classJavaVMStackSOF {private int count = 0;public static voidmain(String[] args) {newJavaVMStackSOF().method();

    }public voidmethod() {

    System.out.println(++count);

    method();

    }

    }

    -Xss为128k。其中的一次测试结果为,当count的值累加到2230时,发生如下异常:

    Exception in thread "main"java.lang.StackOverflowError

    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)

    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:564)

    at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:619)

    at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:561)

    at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)

    at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)

    at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)

    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)

    at java.io.PrintStream.write(PrintStream.java:526)

    at java.io.PrintStream.print(PrintStream.java:597)

    at java.io.PrintStream.println(PrintStream.java:736)

    at com.demo.test.JavaVMStackSOF.method(JavaVMStackSOF.java:15)

    随着-Xss参数值的增大,可以嵌套的方法调用层次也相应增加。综上所述,StackOverflowError异常是由于方法调用的层次太深,最终导致为某个线程分配的所有栈帧大小总和大于-Xss设置的值,从而发生StackOverflowError异常。

    (2)OutOfMemoryError异常

    java程序代码启动一个新线程时,没有足够的内存空间为该线程分配java栈(一个线程java栈的大小由-Xss参数确定),jvm则抛出OutOfMemoryError异常。例子如下:

    packagecom.demo.test;/*** VM Args: -Xss128k*/

    public classJavaVMStackOOM {public static voidmain(String[] args) {int count = 0;while (true) {

    Thread thread= new Thread(newRunnable() {public voidrun() {while (true) {try{

    Thread.sleep(5000);

    }catch(Exception e) {

    }

    }

    }

    });

    thread.start();

    System.out.println(++count);

    }

    }

    }

    -Xss为128k。其中的一次测试结果为,当count的值累加到11958时,发生如下异常:

    Exception in thread "main" java.lang.OutOfMemoryError: unable to create new nativethread

    at java.lang.Thread.start0(Native Method)

    at java.lang.Thread.start(Thread.java:693)

    at com.demo.test.JavaVMStackOOM.main(JavaVMStackOOM.java:21)

    随着-Xss参数值的增大,java程序可以创建的总线程数越少。

    4.所以Server容器启动的时候我们经常关心和设置JVM的几个参数如下:

    -Xms:java Heap初始大小, 默认是物理内存的1/64。

    -Xmx:java Heap最大值,不可超过物理内存。

    -Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一 。增大年轻代后,将会减小年老代大小,可以根据监控合理设置。

    -Xss:每个线程的Stack大小,而最佳值应该是128K,默认值好像是512k。

    -XX:PermSize:设定内存的永久保存区初始大小,缺省值为64M。

    -XX:MaxPermSize:设定内存的永久保存区最大大小,缺省值为64M。

    -XX:SurvivorRatio:Eden区与Survivor区的大小比值,设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。

    -XX:+UseParallelGC:F年轻代使用并发收集,而年老代仍旧使用串行收集。

    -XX:+UseParNewGC:设置年轻代为并行收集,JDK5.0以上,JVM会根据系统配置自行设置,所无需再设置此值。

    -XX:ParallelGCThreads:并行收集器的线程数,值最好配置与处理器数目相等 同样适用于CMS。

    -XX:+UseParallelOldGC:年老代垃圾收集方式为并行收集(Parallel Compacting)。

    -XX:MaxGCPauseMillis:每次年轻代垃圾回收的最长时间(最大暂停时间),如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。

    -XX:+ScavengeBeforeFullGC:Full GC前调用YGC,默认是true。

    实例如:JAVA_OPTS=”-Xms4g -Xmx4g -Xmn1024m -XX:PermSize=320M -XX:MaxPermSize=320m -XX:SurvivorRatio=6″

    第一种OutOfMemoryError: PermGen space

    发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。解决这类问题有以下两种办法:

    1、增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大 小,XX:MaxPermSize是最大永久保存区域大小。如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m" 如果是windows服务器还可以在系统环境变量中设置。感觉用tomcat发布sprint+struts+hibernate架构的程序时很容易发生这种内存溢出错误。使用上述方法,我成功解决了部署ssh项目的tomcat服务器经常宕机的问题。

    2、清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到 tomcat共同的lib下,减少类的重复加载。这种方法是网上部分人推荐的,我没试过,但感觉减少不了太大的空间,最靠谱的还是第一种方法。

    第二种OutOfMemoryError: Java heap space

    发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。解决这类问题有两种思路:

    1、检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。 我以前写一个使用K-Means文本聚类算法对几万条文本记录(每条记录的特征向量大约10来个)进行文本聚类时,由于程序细节上有问题,就导致了 Java heap space的内存溢出问题,后来通过修改程序得到了解决。

    2、增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

    展开全文
  • Java 工作线程OOM,会怎么样? 初看到这一问题,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常 java.lang.OutOfMemoryError: Java heap space 默想如下 在多线程环境下...

    Java 工作线程OOM,其他线程会怎么样?进程会死掉吗

    初看到这一问题,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常

    java.lang.OutOfMemoryError: Java heap space

    默想如下

    在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。

    所以按照这个思路去思考的话,看到这个题目首先就会想到 如果堆内存是共享的话,那么单独的子线程内存溢出也就是堆占用满了 其他线程自然也就不能工作了。然后实验结果却不是这样

    开始实验

    编译工具:IDEA
    内存检测工具:VisualVm

    基本参数设置如下:

    -mx80 -XX:MaxPermSize=50m
    最大可用的堆内存是80M 最大可使用的非堆内存是50m按需分配

    测试参数设置

    测试代码如下

            public static void main(String[] args) {
    
            long memory = Runtime.getRuntime().maxMemory();
            System.out.println(String.format("%d (%.2f M)", memory, (double) memory / (1024 * 1024)));
    
            Thread mThreadTest = new Thread(() -> {
                List<byte[]> list = new ArrayList<byte[]>();
                while (true) {
                    System.out.println(new Date().toString() + Thread.currentThread() + "==");
                    byte[] b = new byte[1024 * 10240 * 1];
                    list.add(b);
                    try {
                        Thread.sleep(3000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            mThreadTest.start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
                        System.out.println("test");
                    }
    
                }
            }).start();
        }
    
    }
    
    

    代码应该比较容易看懂,开了两个工作线程一个,第一个线程每隔3秒分配1m的内存空间,第二个每隔一秒输出一个test

    在这里插入图片描述

    注意看9:43:00 前后,内存到达一个峰值以后立刻就降下来了。并且打印出OutOfMemoryError,打印test的线程仍在继续运行
    在这里插入图片描述
    结论

    `当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,但是其他线程还在继续运行,进程无法恢复。

    展开全文
  • Java内存溢出及解决

    千次阅读 2021-07-29 15:25:55
    一、OutOfMemoryError(内存溢出) JVM 管理的内存大致包括三种区域:Heap space(堆区域)、Java Stacks(Java 栈)、Permanent Generation space(永久保存区域)。由此,OOM 简单的分为堆溢出、栈溢出、永久代溢出(常量池...

    一、OutOfMemoryError(内存溢出)

    JVM 管理的内存大致包括三种区域:Heap space(堆区域)Java Stacks(Java 栈)Permanent Generation space(永久保存区域)。由此,OOM 简单的分为堆溢出、栈溢出、永久代溢出(常量池/方法区)。Java 程序的每个线程中都有一个独立的堆栈。容易发生内存溢出问题的内存空间包括:Heap space 和 Permanent Generation space。

    1️⃣堆区域用来存放 Class 的实例(即对象),对象需要存储的内容主要是非静态属性。每次用 new 创建一个对象实例后,对象实例存储在堆区域中,这部分空间也被 JVM 的垃圾回收机制管理。

    【Java 堆内存溢出】java.lang.OutOfMemoryError: Java heap space此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。原因是 JVM 创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与 Heap space 有关。解决这类问题有两种思路:

    1. 对于内存泄露,可以通过内存监控软件查找程序中的泄露代码。检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。
    2. 增加 JVM 中 Xms(初始堆大小)和 Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

    2️⃣Java 栈跟大多数编程语言包括汇编语言的栈功能相似,主要基本类型变量以及方法的输入输出参数。

    【Java 栈内存溢出】java.lang.StackOverflowError不会抛 OOM error,但也是比较常见的 Java 内存溢出。Java 栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

    3️⃣永久保存区域主要存放 Class 和 Meta 的信息,Class 第一次被 Load 的时候被放入 PermGen space 区域,Class 需要存储的内容主要包括方法和静态属性。

    【Java 永久代溢出】java.lang.OutOfMemoryError: PermGen space即方法区溢出了,一般出现于大量的 jar 或 Class 或者渲染视图(jsp、vm、ftl)页面,或者采用 cglib 等反射机制的情况,因为上述情况会产生大量的 Class 信息存储于方法区,使得 JVM 装载类的空间不够。解决这类问题有以下两种办法:

    1. 增加 JVM 中的初始永久保存区域大小XX:PermSize和最大永久保存区域大小XX:MaxPermSize参数的大小。如针对 tomcat6.0,在 catalina.sh 或 catalina.bat 文件中一系列环境变量名说明结束处(大约在70行左右)增加一行:
      JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"
      如果是 windows 服务器还可以在系统环境变量中设置。
    2. 清理应用程序中 web-inf/lib 下的 jar。如果 tomcat 部署了多个应用,很多应用都使用了相同的 jar,可以将共同的 jar 移到 tomcat 共同的 lib 下,减少类的重复加载。

    二、常见场景

    1️⃣静态集合类声明为静态 staticHashMap、Vector 等集合。通俗来讲A中有B,当前只把B设置为空,A没有设置为空,回收时B无法被回收,因为被A引用。
    2️⃣物理连接:DataSource.getConnection()建立链接,必须通过close()关闭链接
    3️⃣内部类和外部模块等的引用
    GC 只会回收没有被引用或者根集不可到达的对象(取决于 GC 算法),内部类在生命周期内始终持有外部类的对象的引用,造成外部类的对象始终不满足 GC 的回收条件,反映在内存上就是内存泄露。常见解决方案:

    1. 将内部类定义为static
    2. 用static的变量引用匿名内部类的实例或将匿名内部类的实例化操作放到外部类的静态方法中

    4️⃣【OutOfMemoryError:unable to create new native thread】Executors 返回的线程池对象的弊端如下:

    1. FixedThreadPool 和 SingleThreadPool:
      允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
    2. CachedThreadPool 和 ScheduledThreadPool:
      允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。

    三、分析定位

    1️⃣在未明确找到问题原因前,先添配置 JVM 启动参数,监控复原 OOM 场景自动dump:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目录}

    2️⃣

    1. 获取内存的堆信息jmap -dump:format=b,file=mem.dat pid
    2. 使用内存映像分析工具(如Eclipse Memory Analyzer)对 dump 出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。
    3. 看分析图,查找对应问题,分析内存占用情况 例如:localstore 存储问题分析,大对象。
    展开全文
  • 当线程池处理的太慢的时候,队列里的内容会积累,积累到一定程度就会内存溢出。即使没有内存溢出,队列的延迟势必会变大,而且如果进程突然遇到退出信号,队列里的消息还没有被处理就被丢弃了,那必然会对系统的...
  • 所以Server容器启动的时候我们经常关心和设置JVM的几个参数如下:-Xms:java Heap初始大小, 默认是物理内存的1/64。-Xmx:java Heap最大值,不可超过物理内存。-Xmn:young generation的heap大小,一般设置为Xmx的3...
  •  java.lang.OutOfMemoryError: Java heap space:这种是java内存不够,一个原因是真不够,另一个原因是程序中有死循环;  如果是java内存不够的话,可以通过调整JVM下面的配置来解决:  <jvm>-Xms3062m ...
  • 相信有一定java开发经验的人或多或少...在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Hea...
  • 无法新建本机线程7. 杀死进程或子进程8. 发生 stack_trace_with_native_method1. Java 堆空间发生频率:5颗星造成原因无法在 Java 堆中分配对象吞吐量增加应用程序无意中保存了对象引用,对象无法被 GC 回收应用...
  • java内存溢出的原因和解决方法发布时间:2020-06-15 17:57:39来源:亿速云阅读:85作者:元一内存溢出含义:内存溢出(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远...
  • 解释:线程内存溢出, 原因:方法递归调用 OutOfMemoryError:Java heap memory 解释:堆内存溢出 原因:大量对象创建撑爆堆区 OutOfMemoryError:GC overhead limit exceeded 解释:频繁GC且GC无效果 原因:大量...
  • 线程内存溢出处理方式

    千次阅读 2021-05-29 11:02:38
    四、内存溢出怎么办 OOM:OutOfMemory(内存溢出) 开发中常见异常: 1.StackOverFlowError 实例:递归调用后方法特别多,将栈空间撑爆 public class StackOverFlowErrorDemo{ public static void main(){ test(); } ...
  • Java内存溢出及分析

    2020-12-22 23:07:51
    对于内存溢出,首先想到的是C语言,其实不然,java中也有各种的内存...  1,程序计数器:是一个较小的内存空间,是但钱线程的字节码行号指示器,这个不会出现内存溢出。  2,虚拟即栈:虚拟即栈抛出的异常叫做Sta
  • 一日凌晨,手机疯狂报警,短信以摧枯拉朽之势瞬间以百条的速度到达,我在睡梦中被惊醒,看到短信的部分内容如下: ... at java.lang.Thread.start(Thread.java:597) at java.util.Timer.<init&g
  • java内存溢出 原因与排查方法 1、 内存溢出的原因是什么? 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,导致剩余的内存不够用,造成的内存溢出。如果出现这种现象可行代码排查: 一)是否应用...
  •  Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器,Java虚拟机栈,本地方法栈,Java堆,方法区。下面详细...
  • 内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。比方说,定义了20个字节大小的内存空间,却写入了21个字节的数据。通俗的说,就是内存不够,没办法支持当前程序。当发生内存...
  • java内存溢出的2种情况

    千次阅读 2021-02-27 17:38:53
    进过自己一番总结内存溢出主要分为2种:一、堆内存溢出 OutOfMemoryError从jvm的角度看发生的情况是:1、动态扩展的栈内存无法满足内存分配。2、建立新的线程没有足够内存创建栈。从编码角度看发生的情况是:1、内存...
  • 1、 内存溢出的原因是什么?内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc ...
  • java内存溢出的几种原因和解决办法是:第一类内存溢出,也是大家认为最多,第一反应认为是的内存溢出,就是堆栈溢出:那什么样的情况就是堆栈溢出呢?当你看到下面的关键字的时候它就是堆栈溢出了:java.lang....
  • Java垃圾回收机制(GC) 1.1 GC机制作用 1.2 堆内存3代分布(年轻代、老年代...2.3 ML(内存泄露) OOM(内存溢出)问题现象及分析 2.4 IBM DUMP分析工具使用介绍 Java应用CPU、线程问题分析 Java垃圾回收机制(GC)
  • 如果一个线程发生堆内存溢出,或者栈内存溢出,其他线程是否还会继续工作 不废话,先上答案,不管是堆内存溢出,或者栈内存溢出,其余线程都会继续工作 1:首先测试堆内存溢出 **1.1:试用IDEA测试,代码如下:** ...
  • Java线程编程-(1)-线程安全和锁Synchronized概念 Java线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java线程编程-(3)-线程本地ThreadLocal的介绍与使用 Java线程编程-(4)-线程间通信...
  • 下列的java代码是一个模拟线上的内存泄漏的代码,这段代码的业务逻辑是从数据库中读取信用数据,套用模型,并把结果进行记录和传输; 启动 启动时加入参数-Xms200M -Xmx200M -XX:+UseParallelGC -XX:+PrintGC -XX:+...
  • Java内存溢出代码实例

    2019-09-28 20:59:39
    1.什么是内存溢出 JVM运行时可分为虚拟机栈,堆,元空间,程序计数器,本地方法栈等等。在虚拟机管理内存自动内存管理机制下,不需要自己来实现释放内存。但是由于某些操作不当,也可能导致虚拟机异常,比如内存分配...
  • Java内存溢出场景及解决办法

    万次阅读 多人点赞 2018-10-04 21:11:23
    Java内存溢出即程序在申请内存时,没有足够的空间供其使用,出现out of memory。常见于四种情况:栈溢出(StackOverflowError)、堆溢出(OutOfMemoryError:java heap space)、永久代溢出(OutOfMemoryError: Perm...
  • 关于Java Tomcat 内存溢出排查

    千次阅读 2018-07-17 11:14:20
    网站不知道什么时候,开始内存飙升,从 Tomcat 启动后,初始内存占用4%~5% ...一、定位造成内存溢出可能存在的问题 io流操作文档没关闭流。 往一个静态集合变量里一直压栈。 连接没释放。 Java队列没消耗。 ...
  • java csv大数据量导出(千万级别,不会内存溢出),多线程导出 ,生产环境已经很稳定的使用着

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,159
精华内容 43,663
关键字:

java线程内存溢出

java 订阅