JAVA程序内存溢出问题原因分析

本文较为详细的分析了JAVA程序内存溢出问题原因。分享给大家供大家参考。具体如下:

遇到一个线上系统报 java.lang.OutOfMemoryError: PermGen space 错误,需要定位一下问题。很久之前到时弄过这个,现在还真有点不记得了,但这个真的是一个非常有意思的问题,值得好好研究一下。首先第一反应当然是加上-XX:+PrintGCDetails参数来看具体的GC日志,但是由于程序是tomcat启动的,担心里面封装的东西太多不好定位,既然在windows下面,所以还是借助可视化工具好了。
然后我们来看一下这个错误的产生原因,在网上找到一段解释,说的很不错,贴过来借用一下:)
 PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
那么我们先加大PermGen的初始内存大小:

linux下在catalina.sh文件的开头加上:

代码如下:

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m"

windows下在catalina.bat的文件开头加上:

代码如下:

set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256M -XX:MaxPermSize=256m

接着我们还是用可视化的内存查看工具来定位一下具体的问题。对于jdk6首选当然是自带的工具啦,比较常用的有jconsole和jvisualvm(使用后发现后者更强大,因为有丰富的插件支持)。这次又遇到一个比较诡异的问题,就是分析工具打开后居然找不到tomcat进程(事后发现居然启动的是jre,改成jdk应该就可以了)。

既然本地不让连,我就远程连接得了,打开JMX即可。
和上面一样,在catalina.sh或catalina.bat文件的开头的JAVA_OPTS里面加上

代码如下:

-Djava.rmi.server.hostname=192.168.1.101 -Dcom.sun.management.jmxremote.port=9000 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

启动程序以后用netstat查看一下端口是否正确打开,以确保远程可以连接上。
我这里偷懒了下,把authenticate关掉了,要是打开需要设置一些权限的东西,比较麻烦。这个设置在我本地的PC机上生效,但是在服务器上居然不行,可能装了什么软件把端口给封了,所以我只好再犯下贱,把端口改成1000。打开jvisualvm,点击file -> add JMX connection,然后加上localhost:1000就连上了。

等连上程序以后,观察一段时间的内存变化状况,我重点看了下Perm的情况,一直稳定在94m的样子,运行一天一切正常。可能是之前设置Perm内存大小没有生效,因为Perm默认初始化是16m,最大是64m,而实际占用量确实有可能导致这个问题,从目前的现象来看应该是不会再出现这个问题了。如果需要更进一步定位问题,还可以使用btrace去查看某个方法具体被调用的地方。这样可以定位到某些方法是否按预期执行。

希望本文所述对大家的java程序设计有所帮助。

(0)

相关推荐

  • Android性能优化之利用Rxlifecycle解决RxJava内存泄漏详解

    前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学习一下如何解决RxJava引起的内存泄漏,就查到了利用Rxlifecycle开源框架可以解决,今天周末就来学习一下如何使用Rxlifecycle. 引用泄漏的背景: RxJava作为一种响应式编程框架,是目前编程界网红,可谓是家喻户晓,其简洁的编码风格.易用易读的链式方法调用.强大的异步支持等使得R

  • Java中关于内存泄漏出现的原因汇总及如何避免内存泄漏(超详细版)

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.最近自己阅读了大量相关的文档资料,打算做个 总结 沉淀下来跟大家一起分享和学习,也给自己一个警示,以后 coding 时怎么避免这些情况,提高应用的体验和质量. 我会从 java 内存泄漏的基础知识开始,并通过具体例子来说明 Android 引起内存泄漏的各种原因,以

  • Java内存溢出和内存泄露

    虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 一.为什么要了解内存泄露和内存溢出? 1.内存泄露一般是代码设计存在缺陷导致的,通过了解内存泄露的场景,可以避免不必要的内存溢出和提高自己的代码编写水平: 2.通过了解内存溢出的几种常见情况,可以在出现内存溢出的时候快速的定位问题的位置,缩短解决故障的时间.  二.基本概念  理解这两个概念非常重要. 内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存.即被分配的对象可达但已无

  • 完美解决java读取大文件内存溢出的问题

    1. 传统方式:在内存中读取文件内容 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 实际上是使用BufferedReader或者其子类LineNumberReader来读取的. 传统方式的问题: 是文件的所有行都被存放在内存中,当文件足够大时很快就会

  • 编写Java代码制造一个内存溢出的情况

    这将会是一篇比较邪恶的文章,当你想在某个人的生活中制造悲剧时你可能会去google搜索它.在Java的世界里,内存溢出仅仅只是你在这种情况下可能会引入的一种bug.你的受害者会在办公室里度过几天甚至是几周的不眠之夜. 在这篇文章中我将会介绍两种溢出方式,它们都是比较容易理解和重现的.并且它们都是来源现实项目的案例研究,但是为了让你清晰地掌握,我把它们简化了. 不过放心,在我们遇到和解决了很过溢出bug之后,类似的案例将会比你想象得更加普遍. 先来一个进入状态的,在使用HashSet/HashMa

  • 基于Java内存溢出的解决方法详解

    一.内存溢出类型1.java.lang.OutOfMemoryError: PermGen spaceJVM管理两种类型的内存,堆和非堆.堆是给开发人员用的上面说的就是,是在JVM启动时创建:非堆是留给JVM自己用的,用来存放类的信息的.它和堆不同,运行期内GC不会释放空间.如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改

  • 解析Java的JNI编程中的对象引用与内存泄漏问题

    JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互--在 Java 程序中调用 native code:在 native code 中嵌入 Java 虚拟机调用 Java 的代码. JNI 编程在软件开发中运用广泛,其优势可以归结为以下几点: 利用 native code 的平台相关性,在平台相关的编程中彰显优势. 对 native code 的代码重用. native code 底层操作

  • java内存溢出示例(堆溢出、栈溢出)

    堆溢出: 复制代码 代码如下: /** * @author LXA * 堆溢出 */ public class Heap { public static void main(String[] args) { ArrayList list=new ArrayList(); while(true) { list.add(new Heap()); } } } 报错: java.lang.OutOfMemoryError: Java heap space 栈溢出: 复制代码 代码如下: /** * @a

  • JAVA程序内存溢出问题原因分析

    本文较为详细的分析了JAVA程序内存溢出问题原因.分享给大家供大家参考.具体如下: 遇到一个线上系统报 java.lang.OutOfMemoryError: PermGen space 错误,需要定位一下问题.很久之前到时弄过这个,现在还真有点不记得了,但这个真的是一个非常有意思的问题,值得好好研究一下.首先第一反应当然是加上-XX:+PrintGCDetails参数来看具体的GC日志,但是由于程序是tomcat启动的,担心里面封装的东西太多不好定位,既然在windows下面,所以还是借助可视

  • Java服务假死后续之内存溢出的原因分析

    目录 一.现象分析 二.原因排查 三.故障解决 一.现象分析 上篇博客说到,Java服务假死的原因是使用了Guava缓存,30分钟的有效期导致Full GC无法回收内存.经过优化后,已经不再使用Guava缓存,实时查询数据.从短期效果来看,确实解决了无法回收内存的问题,但是服务运行几天后,发现内存又逐渐被占满,Full GC后只能回收一小部分. 从上图可以看出,一次Full GC后,老年代基本上没有回收多少内存,占比从99.86%降到99.70%. 二.原因排查 到底是什么对象占据这么大的内存,

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

    你是否遇到过Java应用程序卡顿或突然崩溃的情况?您可能遇到过Java内存泄漏.在本文中,我们将深入研究Java内存泄漏的确切原因,并推荐一些最好的工具来防止内存泄漏发生. 什么是JAVA内存泄漏? 简单地说,Java内存泄漏是指对象不再被应用程序使用,而是在工作内存中处于活动状态. 在Java和大多数其他编程语言中,垃圾收集器的任务是删除不再被应用程序引用的对象.如果不选中,这些对象将继续消耗系统内存,并最终导致崩溃.有时java内存泄漏崩溃不会输出错误,但通常错误会以java.lang.Ou

  • Java中ThreadLocal 导致内存 OOM 的原因分析

    目录 原因分析 正确的使用方式 原因分析 ThreadLocal 导致内存 OOM 的原因是什么? ThreadLocal 底层通过 ThreadLocalMap 存储数据 源码如下:  当我们使用ThreadLocal.set()时,set的value与key(即业务自己定义的ThreadLocal类)会存储在ThreadLocalMap的Entry[]数组里 源码如下: 其中Entry是实现了一个弱引用WeakReference,Entry的key(即业务方定义的 ThreadLocal类)

  • 导致MyEclipse内存不足的原因分析及解决办法

    1.修改eclipse.ini 在Myeclipse安装目录下G:\MyEclipse8.5\Genuitec\MyEclipse 8.5有一个myeclipse.ini配置文件,设置如下: -vmargs -Xmx512m -XX:MaxPermSize=256m -XX:ReservedCodeCacheSize=64m 2.设置Default VM Arguments 在myEclipse中,打开Windows-> Preferences->Java->Installed JREs

  • .Net程序内存异常的原因及解决

    目录 一.概要 二.场景 三.思路 (1)分析 Part1,分析日志堆积原因 Part2,查找内存泄漏的根本原因 (2)工具 Part3,总结 Part4,彩蛋 一.概要 大概在今年三月份的时候突然被紧急调到另外一个项目组解决线上内存异常问题.经过两周的玩命奋战终于解决了这个问题这里把心路历程及思路分享给大家.希望可以帮助到各位或现在正遇到这样事情的小伙伴提供一些思路. 二.场景 当部门老大找到我的时候,给我描述了这样一段话. "目前服务出现了提交内存异常的问题,目前分析出来可能是日志组件有大量

  • Java 堆内存溢出原因分析

    前言 任何使用过基于 Java 的企业级后端应用的软件开发者都会遇到过这种低劣.奇怪的报错,这些报错来自于用户或是测试工程师: java.lang.OutOfMemoryError:Java heap space. 为了弄清楚问题,我们必须返回到算法复杂性的计算机科学基础,尤其是"空间"复杂性.如果我们回忆,每一个应用都有一个最坏情况特征.具体来说,在存储维度方面,超过推荐的存储将会被分配到应用程序上,这是不可预测但尖锐的问题.这导致了堆内存的过度使用,因此出现了"内存不够&

  • Java常见内存溢出异常分析与解决

    Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等,而Hotspot jvm的实现中,将堆内存分为了三部分,新生代,老年代,持久带,其中持久带实现了规范中规定的方法区,而内存模型中不同的部分都会出现相应的OutOfMemoryError错误,接下来我们就分开来讨论一下.java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因: JVM内存过小.程序不严密,产生了过多的垃圾. 导致OutOfMemor

  • Java内存溢出实现原因及解决方案

    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堆用于储存

  • Java虚拟机内存溢出与内存泄漏

    一.基本概念 内存溢出:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出. 内存泄漏:内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏. 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory: 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间

随机推荐