网站开发项目教程笔记,文山州住房和城乡建设局网站,360浏览器免费网站,phpcms 专题网站模板转载自 Java中的OutOfMemoryError引子#xff1a;今天在Sharding-JDBC官方群里有个哥们称“不连sjdbc不会把内存吃光#xff0c;连sjdbc跑一会就把内存吃光”#xff0c;倍感诧异#xff0c;我们已经用sj很久了#xff0c;一直未发现sj吃内存的情况#xff0c;遂…转载自 Java中的OutOfMemoryError引子今天在Sharding-JDBC官方群里有个哥们称“不连sjdbc不会把内存吃光连sjdbc跑一会就把内存吃光”倍感诧异我们已经用sj很久了一直未发现sj吃内存的情况遂向他要了测试程序。测试之后才发现他所谓的吃内存是报了“java.lang.OutOfMemoryError: unable to create new native thread”的错殊不知创建线程不使用JVM Memory这个报错不是程序吃内存跟sjdbc更是没有关系。他的数据库连接池maxActive30开线程较多时我开了10000个前面的线程没有释放数据库连接后面的线程就要等待造成线程积压最终无法创建新线程自然“unable to create new native thread”。所以还需要扫盲式的向诸位普及一下Java中的内存溢出。1.java.lang.OutOfMemoryError: unable to create new native thread
就是上面例子里面提到的情况。Java中当你创建线程的时候JVM会在JVM 内存创建一个Thread同时创建一个系统本地线程这个系统线程使用的内存不是JVM memory而是系统剩余的内存所以遇到这种情况有时候需要通过“减少内存”的手段来解决指减少堆内存。通常情况下我们有个计算公式来估算能创建线程数的多少countOfThreads(processMaxMemory - JVM Memory - otherOsMemory) / (threadStackSize) 这里的MaxProcessMemory是指一个进程可以占用的最大内存比如在32位window下是2GotherOsMemory是保留的操作系统内存threadStackSize是通过-Xss参数设置的线程栈大小当然还会受到系统最大可创建的线程数量的限制。2.Java.lang.OutOfMemoryError: Java heap space
这种是我们最常见的Java堆溢出我们配置JVM参数时使用-Xms配置堆的最小值使用-Xmx配置堆的最大值通常会将-Xms和-Xmx配置成相同避免堆的自动扩展。Java堆中存放的是对象实例当Java堆中对象达到限制就会产生内存溢出常见的情况有死循环往一个List中添加对象一次性将大文件或者从数据库查询的大批量数据加载到内存中。对于这种情况我们通过JVM配置-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/Data/domains/trans-account/server1/logs来保存内存快照然后用相关内存分析工具进行分析。3. java.lang.OutOfMemoryError: PermGen spacePermGen space的全称是Permanent Generation space是内存的永久保存区域主要存储虚拟机加载的类、常量、静态变量等元数据信息垃圾收集行为在这个区域几乎不出现。对于有大量JSP、大量使用CGLib字节码增强的应用会很容易出现这种错误出现问题时我们经常通过增大-XX:MaxPermSize参数来解决。4. java.lang.OutOfMemoryError: GC overhead limit exceeded
GC overhead limt exceed检查是Hotspot VM定义的一个策略通过统计GC时间来预测是否要OOM了提前抛出异常防止OOM发生。官方对此的定义是“并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作。”这种情况跟第二种情况有重合的地方也是通过检查是否有死循环或者占用大内存的代码当然可以使用-XX:-UseGCOverheadLimit默认是UseGCOverheadLimit来去除GC时间的限制。5. java.lang.OutOfMemoryError: nativeGetNewTLA
这个错误只有在JRockit的JVM上才会遇到大家工作环境中如果都默认使用Hotspot的话应该不会遇到这个问题所以如果大家不感兴趣完全可以不care真的私以为没有业务场景基础的技术意淫都是耍流氓。TLA是Thread Local Area线程本地空间的简写线程本地空间是多线程程序里面为了更有效的进行内存分配而建立的缓存。每一个线程都有一份自己的缓存当这个线程要创建对象的时候就在这上面分配。如果你有很多线程同时并发又要创建大量的对象可能会出现这个问题。6.java.lang.OutOfMemoryError: Requested array size exceeds VM limit
这个错误比较少见除非你真的new了一个非常非常大的数组比如一个亿YOU CAN TRY~当出现这种情况与其去增大JVM的-Xmx不如好好看下你的代码逻辑是不是出现了什么问题。7.java.lang.OutOfMemoryError: request xxxxxx(size) bytes for xxxxxxx(reason). Out of swap space?
额这种情况我真没遇到过不过我们可以了解一下它是当虚拟机向本地操作系统申请内存失败时抛出的。这和你用完了堆或者持久化中的内存的情况有些不同。这个错误通常是在你的程序已经逼近平台限制的时候产生的。这个信息告诉你的是你可能已经用光了物理内存以及虚拟内存了。由于虚拟内存通常是用磁盘作为交换分区因此你最先想到的解决方法可能是先增加交换分区的大小。8.java.lang.OutOfMemoryError: xxxxreason xxxxstack trace(Native method)
这种报错是从native method中抛出的不是JVM执行的方法如果遇到这种情况咳自求多福吧。