精华内容
下载资源
问答
  • java线程池内存溢出
    千次阅读
    2021-03-16 14:07:17

    java内存溢出的原因和解决方法

    发布时间:2020-06-15 17:57:39

    来源:亿速云

    阅读:85

    作者:元一

    内存溢出含义:

    内存溢出(out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。此时软件或游戏就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件。

    java内存溢出的几种原因和解决办法是:

    第一类内存溢出,也是大家认为最多,第一反应认为是的内存溢出,就是堆栈溢出:

    那什么样的情况就是堆栈溢出呢?当你看到下面的关键字的时候它就是堆栈溢出了:

    java.lang.OutOfMemoryError: ......java heap space.....

    也就是当你看到heap相关的时候就肯定是堆栈溢出了,此时如果代码没有问题的情况下,适当调整-Xmx和-Xms是可以避免的,不过一定是代码没有问题的前提,为什么会溢出呢,要么代码有问题,要么访问量太多并且每个访问的时间太长或者数据太多,导致数据释放不掉,因为垃圾回收器是要找到那些是垃圾才能回收,这里它不会认为这些东西是垃圾,自然不会去回收了;主意这个溢出之前,可能系统会提前先报错关键字为:

    java.lang.OutOfMemoryError:GC over head limit exceeded

    这种情况是当系统处于高频的GC状态,而且回收的效果依然不佳的情况,就会开始报这个错误,这种情况一般是产生了很多不可以被释放的对象,有可能是引用使用不当导致,或申请大对象导致,但是java heap space的内存溢出有可能提前不会报这个错误,也就是可能内存就直接不够导致,而不是高频GC.

    第二类内存溢出,PermGen的溢出,或者PermGen 满了的提示,你会看到这样的关键字:

    关键信息为:

    java.lang.OutOfMemoryError: PermGen space

    原因:系统的代码非常多或引用的第三方包非常多、或代码中使用了大量的常量、或通过intern注入常量、或者通过动态代码加载等方法,导致常量池的膨胀,虽然JDK 1.5以后可以通过设置对永久带进行回收,但是我们希望的是这个地方是不做GC的,它够用就行,所以一般情况下今年少做类似的操作,所以在面对这种情况常用的手段是:PermGen的溢出和-XX:MaxPermSize的大小。

    第三类内存溢出:在使用ByteBuffer中的allocateDirect()的时候会用到,很多javaNIO的框架中被封装为其他的方法

    溢出关键字:

    java.lang.OutOfMemoryError: Direct buffer memory

    如果你在直接或间接使用了ByteBuffer中的allocateDirect方法的时候,而不做clear的时候就会出现类似的问题,常规的引用程序IO输出存在一个内核态与用户态的转换过程,也就是对应直接内存与非直接内存,如果常规的应用程序你要将一个文件的内容输出到客户端需要通过OS的直接内存转换拷贝到程序的非直接内存(也就是heap中),然后再输出到直接内存由操作系统发送出去,而直接内存就是由OS和应用程序共同管理的,而非直接内存可以直接由应用程序自己控制的内存,jvm垃圾回收不会回收掉直接内存这部分的内存,所以要注意了哦。

    如果经常有类似的操作,可以考虑设置参数:-XX:MaxDirectMemorySize

    第四类内存溢出错误:

    溢出关键字:

    java.lang.StackOverflowError

    这个参数直接说明一个内容,就是-Xss太小了,我们申请很多局部调用的栈针等内容是存放在用户当前所持有的线程中的,线程在jdk 1.4以前默认是256K,1.5以后是1M,如果报这个错,只能说明-Xss设置得太小,当然有些厂商的JVM不是这个参数,本文仅仅针对Hotspot VM而已;不过在有必要的情况下可以对系统做一些优化,使得-Xss的值是可用的。

    第五类内存溢出错误:

    溢出关键字:

    java.lang.OutOfMemoryError: unable to create new native thread

    上面第四种溢出错误,已经说明了线程的内存空间,其实线程基本只占用heap以外的内存区域,也就是这个错误说明除了heap以外的区域,无法为线程分配一块内存区域了,这个要么是内存本身就不够,要么heap的空间设置得太大了,导致了剩余的内存已经不多了,而由于线程本身要占用内存,所以就不够用了,说明了原因,如何去修改,不用我多说,你懂的。

    第六类内存溢出:

    溢出关键字

    java.lang.OutOfMemoryError: request {} byte for {}out of swap

    这类错误一般是由于地址空间不够而导致。

    六大类常见溢出已经说明JVM中99%的溢出情况,要逃出这些溢出情况非常困难,除非一些很怪异的故障问题会发生,比如由于物理内存的硬件问题,导致了code cache的错误(在由byte code转换为native code的过程中出现,但是概率极低),这种情况内存 会被直接crash掉,类似还有swap的频繁交互在部分系统中会导致系统直接被crash掉,OS地址空间不够的话,系统根本无法启动,呵呵;JNI的滥用也会导致一些本地内存无法释放的问题,所以尽量避开JNI;socket连接数据打开过多的socket也会报类似:IOException: Too many open files等错误信息。

    更多相关内容
  • 线程池处理的太慢的时候,队列里的内容会积累,积累到一定程度就会内存溢出。即使没有内存溢出,队列的延迟势必会变大,而且如果进程突然遇到退出信号,队列里的消息还没有被处理就被丢弃了,那必然会对系统的...

    c73100b1002f56af48d7661df2ad3bfe.png

    Java的Executors框架提供的定长线程池内部默认使用LinkedBlockingQueue作为任务的容器,这个队列是没有限定大小的,可以无限向里面submit任务。

    6576d8aedc251ea5fceeb54e371cc522.png

    当线程池处理的太慢的时候,队列里的内容会积累,积累到一定程度就会内存溢出。即使没有内存溢出,队列的延迟势必会变大,而且如果进程突然遇到退出信号,队列里的消息还没有被处理就被丢弃了,那必然会对系统的消息可靠性造成重大影响。

    那如何解决线程池的过饱问题呢?从队列入手,无外乎两种方法

    增加消费者,增加消费者处理效率

    限制生产者生产速度

    增加消费者就是增加线程池大小,增加消费者处理效率就是优化逻辑处理。但是如果遇到了IO瓶颈,消费者处理的效率完全取决于IO效率,在消费能力上已经优化到了极限还是处理不过来怎么办?或者系统突然遇到用户高峰,我们所配置的线程池大小不够用怎么办?

    这时候我们就只能从生产者入手,限制生产者的生产速度。那如何限制呢?

    LinkedBlockingQueue提供了capacity参数可以限制队列的大小,当队列元素达到上线的时候,生产者线程会阻塞住,直到队列被消费者消费到有空槽的时候才会继续下去。这里似乎只要给队列设置一个大小就ok了。

    但是实际情况并不是我们所想的那样。

    3da797ea022df2012c56c73c0956379d.png

    翻开源码可以发现生产者向队列里塞任务用的方法是workQueue.offer(),这个方法在遇到队列满时是不会阻塞的,而是直接返回一个false,表示抛弃了这个任务。然后生产者调用reject方法,进入拒绝处理逻辑。

    接下来我们看看这个reject方法到底干了什么

    7c92358580c6b85e74bddcf2aad13404.png

    我们看到JDK默认提供了4中拒绝策略的实现。

    AbortPolicy 默认策略,抛出RejectedExecutionException异常

    CallerRunsPolicy 让任务在生产者线程里执行,这样可以降低生产者的生产速度也不会将生产者的线程堵住

    DiscardPolicy 直接抛弃任务,不抛异常

    DiscardOldestPolicy 直接抛弃旧任务,不抛异常

    一般比较常用的是CallerRunPolicy,比较优雅的解决了过饱问题。如果你觉得这种方式不那么优雅的话,还可以使用下面的几种方式。这几种方式都是通过处理RejectExecution来实现生产者的阻塞的目的。

    541f402835c7779d637d45d34337e5a4.png

    这种方案是使用put方法会阻塞生产者线程的原理达到了目的。

    33af71cbd2e3d7a7d04f2ba8fcc8bc0e.png

    这种方案显而易见,用sleep达到了阻塞的目的。

    e4077daadd4714f75742609f12e96866.png

    这种方案是通过信号量的大小都限制队列的大小,也不需要特别限定executor队列大小了

    同样的原理还可以使用wait/notifyAll机制来达到一样的目的。

    展开全文
  • 相信有一定java开发经验的人或多或少...在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Hea...

    相信有一定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。

    http://outofmemory.cn/java/OutOfMemoryError/PermGen-space-Java-heap-space-unable-create-new-native-thread

    http://www.cnblogs.com/wen12128/archive/2011/03/19/1989020.html

    展开全文
  • Java常见的几种内存溢出及解决方案

    千次阅读 2021-02-12 16:58:02
    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

    展开全文
  • 线程池不建议使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 Executors各个方法的弊端: newFixedThreadPool和...
  • 主要介绍了编写Java代码制造一个内存溢出的情况,或许这种有意制造能够更好地帮助理解Java中的内存溢出情况XD 需要的朋友可以参考下
  • 1. 线程池自动关闭的情况一:核心线程数为 0 并指定线程存活时间 1.1手动创建线程池 1.2Executors.newCachedThrteadPool() 创建线程池 2线程池自动关闭的情况二:通过 allowCoreThreadTimeOut 控制核心线程存活...
  • java线程池案例

    2022-03-03 16:34:02
    简介 线程Thread是一个重量级资源,线程的创建、启动以及销毁都是...当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用。 一个线程池包括以下四个基
  • 主要介绍了java线程池工作队列饱和策略代码示例,涉及线程池的简单介绍,工作队列饱和策略的分析及代码示例,具有一定参考价值,需要的朋友可以了解下。
  • java内存溢出

    2022-06-06 12:01:45
    误用固定大小线程池,以下是一个模仿发短信的代码,两个线程进行发短信,并且sleep(30)模拟短信过期时间,由于线程sleep,任务不断产生,堆满了阻塞队列,发生内存溢出。 解决方法:构造线程池的时候,使用有大小...
  • 主要介绍了JAVA 内存溢出案例的汇总,文中讲解非常细致,帮助各位工作学习时避免内存溢出,感兴趣的朋友可以了解下
  • java线程池的理解

    2022-06-02 19:55:42
    1)一般线程在执行完任务之后只有等待被gc回收之后才会释放内存,此时线程会继续占据内存空间,如果不释放内存,那么线程一多就会导致占用内存过多(即内存溢出),因此线程池提供shutdown方法及时释放运行完线程任务的线程...
  • 是常规的堆内存溢出导致的oom吗?创建的线程池对象,会被gc回收吗? [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNfWWDzs-1654603140526)...
  • java线程池配置详解

    千次阅读 2021-07-31 14:55:15
    java线程池配置详解 ThreadPoolExecutor全参构造 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
  • Java线程池技术详解

    2022-06-14 07:10:14
    Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来...
  • Java线程池Executor详解

    万次阅读 2021-12-12 22:12:25
    线程池类图 我们最常使用的Executors实现创建线程池使用线程主要是用上述类图中提供的类。在上边的类图中,包含了一个Executor框架,它是一个根据一组执行策略的调用调度执行和控制异步任务的框架,目的是提供一种将...
  • 下列的java代码是一个模拟线上的内存泄漏的代码,这段代码的业务逻辑是从数据库中读取信用数据,套用模型,并把结果进行记录和传输; 启动 启动时加入参数-Xms200M -Xmx200M -XX:+UseParallelGC -XX:+PrintGC -XX:+...
  • @SpringBootTest class ThreadTestApplicationTests { @Test void contextLoads() { // ExecutorService pools= Executors.newFixedThreadPool(5); ...ExecutorService pools= new ThreadPoolExecutor(4,4,0, ...
  • Java线程池

    千次阅读 2020-06-26 13:37:34
    Java线程的创建、销毁和线程间切换是一件比较耗费计算机资源的。如果我们需要用多线程处理任务,并频繁的创建、销毁线程会造成计算机资源的无端浪费,因此项目中会使用是线程池技术。 一、线程池介绍 1、线程池的...
  • 相信有一定java开发经验的人或多或少...在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Hea...
  • 内存溢出是指程序申请内存时,没有足够的内存供申请者使用;或者说提供一块存储int数据的存储空间,但存储了long数据,则结果是内存不够用,报错OOM。内存泄漏的堆积最终会导致内存溢出。 本教程操作环境:windows7...
  • JAVA线程池的正确使用

    2021-08-11 20:53:10
    参考文章:Java并发编程正确打开线程池的方式 1. 概述 线程可认为是操作系统可调度的最小的程序执行序列,一般作为进程的组成部分,同一进程中多个线程可共享该进程的资源(如内存等)。JVM线程跟内核轻量级进程有...
  • 我们在之前的文章中说明了简单的线程使用方法以及线程池的使用方法。线程数一直增加的问题普通简单多线程的使用方式是Thread t=new Thread();t.start();//启动线程对象t但是在web项目中发现查看控制台这种情况会导致...
  • Java 线程池 ThreadPoolExecutor

    千次阅读 2021-06-07 21:32:55
    Java 线程池 ThreadPoolExecutor
  • Java内存溢出及解决

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

    2022-05-22 21:16:42
    常见的运用池化思想的有:内存池、数据库连接池。使用线程池的优点如下: 1、降低资源的消耗:使得线程可以重复使用,不需要在创建线程和销毁线程上浪费资源 2、提高响应速度:任务到达时,线程可以不需要创建即可以...
  • 涵盖栈深度溢出、永久代内存溢出、本地方法栈溢出、JVM栈内存溢出和堆溢出,让你彻底理解内存溢出!!
  • 线程池不用反复创建线程达到线程的复用,更具配置合理利用cpu和内存减少了开销,性能会得到提高,还能统一管理任务 比如服务器收到大量请求,每个请求都分配线程去处理,对服务器性能考验就比较大,如果创建5个以上...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,717
精华内容 10,286
关键字:

java线程池内存溢出