精华内容
下载资源
问答
  • 文章目录出现的场景如何排查如何注意 Java溢出的场景。 的大小 -XSS设置:...-xx:+HeapDumpOnOutOfMemoryError 参数可以发生OOM时自动进行dump jmap 可以手动 dump jdk 自带的jvisualvm.exe 进行分析 如何注意

    Java栈溢出的场景。

    栈的大小 -XSS设置:JDK5.0后每个堆栈大小为1M(以前是256k)

    Linux 栈默认为8M

    出现的场景

    1. 局部数组过大。
    2. 指针或者数组越界
    3. 递归调用层次太多(字符串拷贝等)

    如何排查

    dump 快照文件利用自带的vm等工具分析

    1. -xx:+HeapDumpOnOutOfMemoryError 参数可以发生OOM时自动进行dump
    2. jmap 可以手动 dump
    3. jdk 自带的jvisualvm.exe 进行分析

    如何注意

    1. 增大栈空间
    2. 改用动态分配,使用堆(heap)而不是栈(stack)
    3. 直接查询生产环境服务器内存占用情况,通过命令定位到具体的那行代码
    展开全文
  • 一、在Java虚拟机规范中,对【虚拟机】这个内存区域规定了两种异常状况:  (1)如果线程请求的【深度】大于虚拟机所允许的深度,将抛出StackOverflowError异常;  (2)如果虚拟机可以动态扩展(当前大...

    一、在Java虚拟机规范中,对【虚拟机栈】这个内存区域规定了两种异常状况:

          (1)如果线程请求的【栈深度】大于虚拟机所允许的深度,将抛出StackOverflowError异常;

          (2)如果虚拟机栈可以动态扩展(当前大部分的 Java 虚拟机都可动态扩展,只不过 Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

          (3)与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和OutOfMemoryError 异常。

    二、对于虚拟机栈和本地方法栈 如果在多线程的情况下是可能出现OOM的,下边就是一个单线程的案例。演示一下:

    /**
     * 设置 VM Args: -Xss128k
     */
    public class JavaVMStackSOF {
    
        private int stackLength = 1;
    
        //反复调用
        public void stackLeak(){
            stackLength++;
            stackLeak();
        }
    
        public static void main(String [] args){
            JavaVMStackSOF oom = new JavaVMStackSOF();
            try {
                oom.stackLeak();
            }catch (Throwable e){
                System.out.println("stack length:" + oom.stackLength);
                throw e;
            }
        }
    }
    

    要设置VM Args: -Xss128k(设置栈为128k),结果如下:

    stack length:995
    Exception in thread "main" java.lang.StackOverflowError
        at com.adonai.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12)
        at com.adonai.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13)

    结果表明:在单线程下,无论是由于栈帧太大,还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常,而不是OOM。

    三、如果测试时不限于单线程,通过不断地建立线程的方式倒是可以产生内存溢出异常。

          自己可以创建多个线程,进行测试

          但是:由于在Windows 平台的虚拟机中, Java 的线程是映射到操作系统的内核线程上的,所以多线程代码执行时有较大的风险,可能会导致操作系统假死。

         不过结果肯定是,多线程的情况下,是会出现OOM的!

    原理如下:

       为什么多线程的情况下就会产生OOM,这样产生的内存溢出异常与栈空间是否足够大并不存在任何联系,或者准确地说,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。

      原因其实不难理解,操作系统分配给每个进程的内存是有限制的,譬如 32 位的 Windows 限制为 2GB。虚拟机提供了参数来控制 Java 堆和方法区的这两部分内存的最大值。剩余的内存为 2GB(操作系统限制)减去 Xmx(最大堆容量),再减去 MaxPermSize(最大方法区容量),程序计数器消耗内存很小,可以忽略掉。如果虚拟机进程本身耗费的内存不计算在内,剩下的内存就由虚拟机栈和本地方法栈“瓜分”了。每个线程分配到的栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。

     更简单理解的就是:有一个操作系统为2G,我们分配给两个线程,每个800M,也就还剩400M,这样的话,有一个线程不够用的话,就会在400里边申请,所以如果剩下的越多,出现OOM的可能性越小,如果每个分配950M,这样就剩100M,这样的话出现OOM的可能性就更大。如果在增加线程,系统对每一个线程非配的内存是一定的,所以剩下的内存更少,这样的话,出现OOM的可能更大,但这都是相对而说。

    遇到OOM这时候我们应该怎么做:

      如果是建立过多线程导致的内存溢出,在不能减少线程数或者更换 64 位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。

      如果没有这方面的经验,这种通过“减少内存”的手段来解决内存溢出的方式会比较难以想到。这种拆东墙补西墙的方法,还是自己意会吧。

     

     

    展开全文
  • 一、在 Java 虚拟机规范中,对虚拟机这个区域规定了两种异常状况:(1)如果线程请求的深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常; (2)如果虚拟机可以动态扩展(当前大部分的 Java ...

    一、在 Java 虚拟机规范中,对虚拟机栈这个区域规定了两种异常状况:

    (1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常;
    (2)如果虚拟机栈可以动态扩展(当前大部分的 Java 虚拟机都可动态扩展,只不过 Java 虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出 OutOfMemoryError 异常。
    (3)与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和OutOfMemoryError 异常。

    二、前一篇文章中的第一张图也看出来了对于虚拟机栈和本地方法栈 如果在多线程的情况下是可能出现OOM的,下边就是一个单线程的案例。演示一下:

    /**
     * 设置  VM Args: -Xss128k
     * @author xuliugen
     *
     */
    public class JavaVMStackSOF {
        private int stackLength = 1;
    
        //反复调用
        public void stackLeak() {
            stackLength++;
            stackLeak();
        }
    
        public static void main(String[] args) throws Throwable {
            JavaVMStackSOF oom = new JavaVMStackSOF();
            try {
                oom.stackLeak();
            } catch (Throwable e) {
                System.out.println("stack length:" + oom.stackLength);
                throw e;
            }
        }
    }

    要设置VM Args: -Xss128k(上一篇已经说到:设置栈为128k),结果如下:

    stack length:40550
    Exception in thread "main" java.lang.StackOverflowError
        at com.lc.oom.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:8)
        后续很多异常省略。。。

    结果表明:在单个线程下,无论是由于栈帧太大,还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是 StackOverflowError 异常,而不是OOM。

    三、如果测试时不限于单线程,通过不断地建立线程的方式倒是可以产生内存溢出异常。自己可以创建多个线程,进行测试,但是:由于在Windows 平台的虚拟机中, Java 的线程是映射到操作系统的内核线程上的,所以多线程代码执行时有较大的风险,可能会导致操作系统假死。所以。。。

    不过结果肯定是,多线程的情况下,是会出现OOM的!

    原理如下:

    为什吗多线程的情况下就会产生OOM,这样产生的内存溢出异常与栈空间是否足够大并不存在任何联系,或者准确地说,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。

    原因其实不难理解,操作系统分配给每个进程的内存是有限制的,譬如 32 位的 Windows 限制为 2GB。虚拟机提供了参数来控制 Java 堆和方法区的这两部分内存的最大值。剩余的内存为 2GB(操作系统限制)减去 Xmx(最大堆容量),再减去 MaxPermSize(最大方法区容量),程序计数器消耗内存很小,可以忽略掉。如果虚拟机进程本身耗费的内存不计算在内,剩下的内存就由虚拟机栈和本地方法栈“瓜分”了。每个线程分配到的栈容量越大,可以建立的线程数量自然就越少,建立线程时就越容易把剩下的内存耗尽。

    更简单理解的就是:有一个操作系统为2G,我们分配给两个线程,每个800M,也就还剩400M,这样的话,有一个线程不够用的话,就会在400里边申请,所以如果剩下的越多,出现OOM的可能性越小,如果每个分配950M,这样就剩100M,这样的话出现OOM的可能性就更大。如果在增加线程,系统对每一个线程非配的内存是一定的,所以剩下的内存更少,这样的话,出现OOM的可能更大,但这都是相对而说。

    遇到OOM这时候我们应该怎么做:

    如果是建立过多线程导致的内存溢出,在不能减少线程数或者更换 64 位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。如果没有这方面的经验,这种通过“减少内存”的手段来解决内存溢出的方式会比较难以想到。这种拆东墙补西墙的方法,还是自己意会吧。

    展开全文
  • OOM与调优的思路

    2020-10-18 21:49:01
    文章目录哪些区域会OOM堆区区元空间(方法区)本地方法调优思路调优的阶段上线前、预估调优上线初期、基于日志简单调优OOM 、频繁full gc调优参数布尔类型逃逸分析key-value 类型缩写案例分析如何调优 ...
    展开全文
  • 文章目录Pre一个线程调用多个方法的入栈和出栈每次方法调用的桢都是要占用内存的到底什么情况下会导致JVM中的内存溢出?一般什么情况下会发生内存溢出?Case Demo重新分析一下JVM中的内存Review内存溢出的...
  • OOM

    千次阅读 2019-01-22 16:38:16
    OOM问题总结什么是OOM为什么会OOMOOM的类型OOM处理方式 什么是OOM OOM ,全称"OutOfMemery",中文名称“内存不够用”。 很长时间以来,很多人都知道jvm内存调优是java知识中的重要组成部分,但是缺乏应用...
  • 虚拟机和本地方法栈OOM测试2

    千次阅读 2012-08-25 23:45:56
     * function:创建线程导致内存溢出异常 虚拟机和本地方法异常  * VM Args:-Xss2M  * @author ylchou@qq.com  *  */ public class JavaVMStackOOM {  private void dontStop(){  while(true){
  • JAVA虚拟机OOM与SOF

    2020-04-07 11:44:13
    JAVA虚拟机 在虚拟机规范中,这部分内存是用来描述方法执行时的数据结构,因此在此部分内存中,主要存储了方法运行时的数据。例如方法的出口,方法的参数,方法中的局部变量等。 JAVA的栈帧 JAVA的虚拟机是每个...
  • oom

    2017-10-19 16:11:04
    最近查找了很多关于OOM,甚至于Java内存管理以及JVM的相关资料,发现这方面的东西太多了,竟有一种眼花缭乱的感觉,要想了解全面的话,恐非一篇文章能说清的,因此按照自己的理解整理了一篇,剩下的还需要继续学习。...
  • 文章目录堆内存溢出虚拟机和本地方法溢出jvm容量太小栈帧太大太小,导致线程分配少,创建更多的线程将导致oom 堆内存溢出 eclipse memory analyzer分析dump package ch2; import java.util.ArrayList; ...
  • 也有OOM和SOF StackOverflowError 溢出: 就是不断压栈直到爆了,超过了当前线程的内存的实际大小。 OOM: 概念是,如果支持动态扩展,那么这个会请求再扩展部分空间。当然内存不是无穷的,如果...
  • 写一个程序让jvm溢出 根据jvm的原理,中存放的是方法,因此我们一直创建方法下去,内存会溢出。这里我想到的是递归不停止,空间肯定会溢出,我们用try-catch看递归调用几次。 package cn.itcast.test; ...
  • 关于虚拟机和本地方法,在JVM规范中描述了两种异常: 1.如果线程请求的深度大于JVM所允许的深度,将抛出StackOverflowError异常; 2.如果虚拟机在扩展时无法申请到足够的内存,就会抛出OutOfMemoryError...
  • 目录 Java (Stack) 堆(Heap) 堆 VS 本文可以结合《Sun JVM 内存管理、GC 工作流程、JVM 参数与...1、Java 是与每一个线程关联的,JVM 在创建每一个线程的时候,会分配一定的空间给线程,Java Stac...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,577
精华内容 12,630
关键字:

oom栈