堆溢出的代码Java 堆溢出的原因及解决办法
java内存溢出是什么情况?
首先先说一下JVM内存结构问题,JVM为两块:PermanentSapce和HeapSpace,其中\x0d\x0aHeap = }。PermantSpace负责保存反射对象,一般不用配置。JVM的Heap区可以通过-X参数来设定。\x0d\x0a 当一个URL被访问时,内存申请过程如下:\x0d\x0aA. JVM会试图为相关Java对象在Eden中初始化一块内存区域\x0d\x0aB. 当Eden空间足够时,内存申请结束。否则到下一步\x0d\x0aC. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区\x0d\x0aD. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区\x0d\x0aE. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)\x0d\x0aF. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”\x0d\x0a\x0d\x0aJVM调优建议:\x0d\x0a\x0d\x0ams/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。\x0d\x0aNewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。\x0d\x0aPermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。\x0d\x0aSurvivorRatio:设置Survivor空间和Eden空间的比例\x0d\x0a\x0d\x0a内存溢出的可能性\x0d\x0a\x0d\x0a1. OLD段溢出\x0d\x0a这种内存溢出是最常见的情况之一,产生的原因可能是:\x0d\x0a1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)\x0d\x0a2) 程序问题\x0d\x0a单个程序持续进行消耗内存的处理,如循环几千次的字符串处理,对字符串处理应建议使用StringBuffer。此时不会报内存溢出错,却会使系统持续垃圾收集,无法处理其它请求,相关问题程序可通过Thread Dump获取(见系统问题诊断一章)单个程序所申请内存过大,有的程序会申请几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,对此首先要找到相关功能,然后交予程序员修改,要找到相关程序,必须在Apache日志中寻找。\x0d\x0a当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认为他还是活跃的对象而不进行回收,这样累计占用了大量内存而无法释放。由于目前市面上还没有对系统影响小的内存分析工具,故此时只能和程序员一起定位。\x0d\x0a\x0d\x0a2. Perm段溢出\x0d\x0a通常由于Perm段装载了大量的Servlet类而导致溢出,目前的解决办法:\x0d\x0a1) 将PermSize扩大,一般256M能够满足要求\x0d\x0a2) 若别无选择,则只能将servlet的路径加到CLASSPATH中,但一般不建议这么处理\x0d\x0a\x0d\x0a3. C Heap溢出\x0d\x0a系统对C Heap没有限制,故C Heap发生问题时,Java进程所占内存会持续增长,直到占用所有可用系统内存\x0d\x0a\x0d\x0a参数说明:\x0d\x0a\x0d\x0aJVM 堆内存(heap)设置选项 \x0d\x0a 参数格式 \x0d\x0a 说 明 \x0d\x0a \x0d\x0a设置新对象生产堆内存(Setting the Newgeneration heap size) \x0d\x0a -XX:NewSize \x0d\x0a 通过这个选项可以设置Java新对象生产堆内存。在通常情况下这个选项的数值为1 024的整数倍并且大于1MB。这个值的取值规则为,一般情况下这个值-XX:NewSize是最大堆内存(maximum heap size)的四分之一。增加这个选项值的大小是为了增大较大数量的短生命周期对象 \x0d\x0a\x0d\x0a增加Java新对象生产堆内存相当于增加了处理器的数目。并且可以并行地分配内存,但是请注意内存的垃圾回收却是不可以并行处理的 \x0d\x0a \x0d\x0a设置最大新对象生产堆内存(Setting the maximum New generation heap size) \x0d\x0a -XX:MaxNewSize \x0d\x0a 通过这个选项可以设置最大Java新对象生产堆内存。通常情况下这个选项的数值为1 024的整数倍并且大于1MB \x0d\x0a\x0d\x0a其功用与上面的设置新对象生产堆内存-XX:NewSize相同\x0d\x0a\x0d\x0a设置新对象生产堆内存的比例(Setting New heap size ratios) \x0d\x0a -XX:SurvivorRatio \x0d\x0a 新对象生产区域通常情况下被分为3个子区域:伊甸园,与两个残存对象空间,这两个空间的大小是相同的。通过用-XX:SurvivorRatio=X选项配置伊甸园与残存对象空间(Eden/survivor)的大小的比例。你可以试着将这个值设置为8,然后监控、观察垃圾回收的工作情况\x0d\x0a\x0d\x0a设置堆内存池的最大值(Setting maximum heap size) \x0d\x0a -Xmx \x0d\x0a 通过这个选项可以要求系统为堆内存池分配内存空间的最大值。通常情况下这个选项的数值为1 024的整数倍并且大于1 MB \x0d\x0a\x0d\x0a一般情况下这个值(-Xmx)与最小堆内存(minimum heap size _Xms)相同,以降低垃圾回收的频度 \x0d\x0a \x0d\x0a取消垃圾回收 \x0d\x0a -Xnoclassgc \x0d\x0a 这个选项用来取消系统对特定类的垃圾回收。它可以防止当这个类的所有引用丢失之后,这个类仍被引用时不会再一次被重新装载,因此这个选项将增大系统堆内存的空间 \x0d\x0a \x0d\x0a设置栈内存的大小 \x0d\x0a -Xss \x0d\x0a 这个选项用来控制本地线程栈的大小,当这个选项被设置的较大(2MB)时将会在很大程度上降低系统的性能。因此在设置这个值时应该格外小心,调整后要注意观察系统的性能,不断调整以期达到最优 \x0d\x0a \x0d\x0a最后说一句,你的机器的连接数设置也至关重要,连接的关闭最好把时间设置的少些,那些连接非常耗费资源。也是引起内存泄露的主要原因。
成都创新互联公司是一家专业提供定兴企业网站建设,专注与成都网站建设、网站建设、H5技术、小程序制作等业务。10年已为定兴众多企业、政府机构等服务。创新互联专业网络公司优惠进行中。
Java堆栈溢出的机制与原理
Java堆栈溢出的出现 很让人痛苦的事情 很多时候都无法找到头绪 这里作者通过使用jrockit调用程序才最终发现了问题的所在 在很多情况下 Java堆栈溢出 很有可能是你的代码中用到数组 到你的索引超出范围了
java lang OutOfMemoryError: Java heap space
在Java程序运行中可能会报如上的错误 通常是在运行过程中内存占用了没有别释放造成的
以前可能没法跟踪可能是很痛苦的事情 现在好了 我们有一个调试软件可以用了 在生产环境下使用的jRockit软件进行调试 是Oracle公司出品的
前两天试用了一下真的很不错
前阵子有个程序跑 个礼拜左右就会出现Java堆栈溢出 始终找不到头绪 后来使用jrockit才找到问题的出处
jrockit是可以调试远程程序也可以调试本地程序的
具体调试步骤
(一)
如果是调试本地程序的话 启动jrockit 然后启动本地需要调试的程序 会在左侧工具栏 本地目录下创建一个连接为需要调试的程序 在上面点击右键 就会启动跟踪
如何跟踪呢 我的办法就是等 在跟踪开始后 进行截图 然后等程序运行一段时间后查找堆增长比较大的并且一直没有释放的变量
(二)
然后在上面点击右键 显示分配跟踪
(三)
然后找到对应的方法 然后就去找问题吧 看看是不是那个地方有内存一直没有释放啊
然后说点我自己的小经验 也许是不对的 但是我在我的应用里面确实是有效的
在经常需要调用的地方将变量设成全局的甚至是静态的 我的操作是设成全局的了 图省事呢 呵呵 因为我的变量时全局都要调用的而且是频繁调用的
用完的变量一定要记得让它等于null 否则执行gc()貌似是不给回收的
基本上jrockit跟踪是很强的 都能够找到你的问题所在 要仔细观察 改完程序后记得再重新跟踪下直到没有内存泄露为止
写完手工
lishixinzhi/Article/program/Java/hx/201311/26094
java堆栈溢出-递归
程序逻辑中永远跳不出递归调用,因为在test中所有逻辑分支中都是往下递归调用,没有终止的逻辑步骤。和方法自己调用自己没有区别。
需要在某个逻辑分支中返回(终止递归)。
java堆内存溢出
调整虚拟机参数,加大heap space 的大小 或者 分批获取数据。
虚拟机参数配置的话可以参考:
-Xms1024m -Xmx1024m -Xmn300m -XX:PermSize=64m -XX:MaxPermSize=128m
具体配置项含义建议去网上查查。不管你是使用本地应用还是web应用都可以配置的。
文章名称:堆溢出的代码Java 堆溢出的原因及解决办法
网页地址:http://myzitong.com/article/hjjdjc.html