精华内容
下载资源
问答
  • 内存溢出和栈溢出
    2017-09-24 15:24:26

    内存溢出和内存泄露的区别:

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

    内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

    memory leak会最终会导致out of memory!

    内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。      内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。    以发生的方式来分类,内存泄漏可以分为4类: 

    ① 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 
    ② 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。 
    ③ 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。 
    ④ 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。 

    从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

    
    

    import java.util.ArrayList;  
    import java.util.List;  
      
    public class a5 {  
        public static int c = 0;  
        public static int d = 0;  
        public static List<String> list = new ArrayList<String>();  
      
    //    如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。--无限递归  
    //    如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 --占用的空间太大  
      
        public static void main(String[] args) {  
        	a5 main = new a5();  
    //        main.testStackOverflowError(c);  
            main.addString(d);  
        }  
      
        public void testStackOverflowError(int c) {//StackOverflowError  
            System.out.println(c++);//10444  
            testStackOverflowError(c);  
        }  
      
      
        public void addString(int d) {//OutOfMemoryError  
            while (true) {  
                System.out.println(d++);//2702970  
                String s = "11111111111111111111111111111111111111111111111111111111";  
                list.add(s + s + s + s + s);  
            }  
        }  
      
    }  


    更多相关内容
  • java内存溢出和栈溢出

    2018-06-08 00:54:27
    出自:https://blog.csdn.net/lirenzuo/article/details/71710543一、背景知识1、JVM体系结构2、JVM运行时数据区3、JVM内存模型JVM运行时内存 = 共享内存区 + 线程内存区3-1、共享内存区共享内存区 = 持久带 + 堆...

    出自:https://blog.csdn.net/lirenzuo/article/details/71710543

    一、背景知识


    1、JVM体系结构




    2、JVM运行时数据区




    3、JVM内存模型


    JVM运行时内存 = 共享内存区 + 线程内存区




    3-1、共享内存区


    共享内存区 = 持久带 + 堆

    持久带 = 方法区 + 其他

    堆 = Old Space + Young Space

    Young Space = Eden + S0 + S1




    3-1-1、持久代


    JVM用持久带(Permanent Space)实现方法区,主要存放所有已加载的类信息,方法信息,常量池等等。

    可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值

    Permanent Space并不等同于方法区,只不过是Hotspot JVM用Permanent Space来实现方法区而已,有些虚拟机没

    有Permanent Space而用其他机制来实现方法区。


    3-1-2、堆


    堆(heap),主要用来存放类的对象实例信息(包括new操作实例化的对象和定义的数组)。

    堆分为Old Space(又名,Tenured Generation)和Young Space。

    Old Space主要存放应用程序中生命周期长的存活对象;

    Eden(伊甸园)主要存放新生的对象;

    S0和S1是两个大小相同的内存区域,主要存放每次垃圾回收后Eden存活的对象,作为对象从Eden过渡到Old Space

    的缓冲地带(S是指英文单词Survivor Space)。

    堆之所以要划分区间,是为了方便对象创建和垃圾回收,后面垃圾回收部分会解释。


    3-2、线程内存区


    线程内存区=单个线程内存+单个线程内存+.......

    单个线程内存=PC Regster+JVM栈+本地方法栈

    JVM栈=栈帧+栈帧+.....

    栈帧=局域变量区+操作数区+帧数据区




    Java中,一个线程会对应一个JVM栈(JVM Stack),JVM栈里记录了线程的运行状态。

    JVM栈以栈帧为单位组成,一个栈帧代表一个方法调用。栈帧由三部分组成:局部变量区、操作数栈、帧数据区。


    二、堆溢出


    堆(Heap)是Java存放对象实例的地方。

    堆溢出可以分为以下两种情况,这两种情况都会抛出OutOfMemoryError:Java heap space异常:


    1、内存泄漏


    内存泄漏是指对象实例在新建和使用完毕后,仍然被引用,没能被垃圾回收释放,一直积累,直到没有剩余

    内存可用。

    如果内存泄露,我们要找出泄露的对象是怎么被GC ROOT引用起来,然后通过引用链来具体分析泄露的原因。

    分析内存泄漏的工具有:Jprofiler,visualvm等。


    示例代码:

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. package com.jvm;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5. import java.util.UUID;  
    6.   
    7. /** 
    8.  * 内存泄漏 
    9.  * @author feizi 
    10.  * @time 2015-1-23上午8:42:53 
    11.  */  
    12. public class OOMTest {  
    13.   
    14.     public static void main(String[] args) {  
    15.           
    16.         List<UUID> list = new ArrayList<UUID>();  
    17.         while(true){  
    18.             list.add(UUID.randomUUID());  
    19.         }  
    20.     }  
    21.   
    22. }  



    看看控制台的输出结果,因为我这边的JVM设置的参数内存足够大,所以需要等待一定的时间,才能看到效果:






    如果是用CMD命令行,就可以自己指定参数编译运行了,这样效果就更快一些:

    通过下列命令运行程序,注意先要用javac命令将.java源文件编译成.class类字节码文件。


    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. java -Xms10M -Xmx10M -XX:-UseGCOverheadLimit OOMTest  


    2、内存溢出


    内存溢出是指当我们新建一个实力对象时,实例对象所需占用的内存空间大于堆的可用空间。

    如果出现了内存溢出问题,这往往是程序本生需要的内存大于了我们给虚拟机配置的内存,这种情况下,我们可以采用调大-Xmx来解决这种问题。


    示例代码:

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. package com.jvm;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. /** 
    7.  * 内存溢出 
    8.  * @author feizi 
    9.  * @time 2015-1-23上午8:56:22 
    10.  */  
    11. public class OOMTest_1 {  
    12.     public static void main(String args[]){  
    13.         List<byte[]> byteList = new ArrayList<byte[]>();  
    14.         byteList.add(new byte[1000 * 1024 * 1024]);  
    15.     }  
    16. }  



    看看控制台的运行效果:




    使用CMD命令行指定参数运行:


    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. java -verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC OOMTest_1  




    三、线程栈


    栈(JVM Stack)存放主要是栈帧( 局部变量表, 操作数栈 , 动态链接 , 方法出口信息 )的地方。注意区分栈和栈帧:栈里包含栈帧。

    与线程栈相关的内存异常有两个:

    a)、StackOverflowError(方法调用层次太深,内存不够新建栈帧)

    b)、OutOfMemoryError(线程太多,内存不够新建线程)


    1、java.lang.StackOverflowError


    栈溢出抛出java.lang.StackOverflowError错误,出现此种情况是因为方法运行的时候,请求新建栈帧时,

    栈所剩空间小于战帧所需空间。

    例如,通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常 :


    示例代码:

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. package com.jvm;  
    2. /** 
    3.  * 栈溢出 
    4.  * @author feizi 
    5.  * @time 2015-1-23上午9:13:11 
    6.  */  
    7. public class SOFTest {  
    8.   
    9.     public void stackOverFlowMethod(){  
    10.         stackOverFlowMethod();  
    11.     }  
    12.       
    13.     /** 
    14.      * 通过递归调用方法,不停的产生栈帧,一直把栈空间堆满,直到抛出异常 : 
    15.      * @param args 
    16.      */  
    17.     public static void main(String[] args) {  
    18.         SOFTest sof = new SOFTest();  
    19.         sof.stackOverFlowMethod();  
    20.     }  
    21.   
    22. }  


    看看控制台运行的效果:



    展开全文
  • 栈溢出和内存溢出的区别

    千次阅读 2019-04-19 11:39:02
    对于一台服务器而言,每一个用户请求,都会产生一个线程来处理这个请求,每一个线程对应着一个栈,栈会分配内存,此时如果请求过多,这时候内存不够了,就会发生栈内存溢出。 什么时候会发生栈溢出栈溢出是指...

    解释图:

    上图是jvm内存模型中最为重要的三部分,方法区中存储的是类模板,堆中存放的是实例对象,每个线程都会生成一个栈。

    何时发生栈内存溢出?

    对于一台服务器而言,每一个用户请求,都会产生一个线程来处理这个请求,每一个线程对应着一个栈,栈会分配内存,此时如果请求过多,这时候内存不够了,就会发生栈内存溢出。

    什么时候会发生栈溢出?

    栈溢出是指不断的调用方法,不断的压栈,最终超出了栈允许的栈深度,就会发生栈溢出,比如递归操作没有终止,死循环。

    帮助记忆:

    可以把内存比作是一个大箱子,栈是一个小箱子,栈溢出是指小箱子装不下了;而栈内存溢出是大箱子在也装不下小箱子了。

    展开全文
  • 栈溢出和内存溢出

    千次阅读 2020-03-31 13:55:25
    内存溢出是指用户栈的大小最多为8~10MB,分配超过栈大小的变量则会导致栈内存溢出。 如char c[1024102411];//11MB 栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其...

    栈内存溢出是指用户栈的大小最多为8~10MB,分配超过栈大小的变量则会导致栈内存溢出。
    如char c[1024102411];//11MB

    栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。

    	char c[10];
        memset(c,'a',10);
        char a[20];
        memset(a,'b',20);
        memcpy(c,a,15);
    

    发生栈溢出的基本前提是:
    程序必须向栈上写入数据
    写入的数据大小没有被良好地控制

    函数调用栈的内存分布:
    在这里插入图片描述
    所谓栈溢出攻击是指通过修改栈中函数的返回地址使得程序转移到攻击性的代码段。比如将函数的返回地址替换成jmp xxx指令的地址,那么函数就会去执行jmp xxx指令,然后xxx就是攻击代码的地址。

    那为什么没有堆溢出攻击呢?因为函数的返回地址是存储在栈中的,堆中一般只存储数据。

    参考:
    https://blog.csdn.net/sinat_31054897/article/details/82223889

    展开全文
  • 什么时候会发生栈溢出? 帮助记忆: 解释图: 上图是jvm内存模型中最为重要的三部分,方法区中存储的是类模板,堆中存放的是实例对象,每个线程都会生成一个栈。 何时发生栈内存溢出? 对于一台服务器而言,...
  • 主要从以下几部分来说明,关于内存内存泄露、溢出的概念,区分内存泄露和内存溢出;内存的区域划分,了解GC回收机制;重点关注如何去监控发现内存问题;此外分析出问题还要如何解决内存问题。下面就开始本篇的...
  • Java 中(堆溢出、内存溢出栈溢出
  • 栈溢出内存溢出

    2020-06-03 12:26:10
    何时发生栈内存溢出? 对于一台服务器而言,每一个用户请求,都会产生一个线程来处理这个请求,每一个线程对应着一个会分配内存,此时如果请求过多,这时候内存不够了,就会发生栈内存溢出。 什么时候会发生...
  • 内存溢出 创建了大量线程、对象,导致垃圾回收器来不及回收,分配的堆内存被占满,产OutOfMemoryError错误。 产生栈溢出的场景:比如死循环中创建对象。 内存泄漏 当很多对象使用之后已经没有再使用的必要而没有置为...
  • 文章目录Java中OutOfMemoryError(内存溢出)的情况及解决办法OutOfMemoryError...StackOverflowError(栈溢出) Java中OutOfMemoryError(内存溢出)的情况及解决办法 除了程序计数器外,虚拟机内存其他运行时区域都会发
  • 主要介绍了java内存溢出示例(堆溢出、栈溢出),需要的朋友可以参考下
  • 1、首先复习一下基础知识。 从物理上讲,堆栈是就是一段连续分配的内存空间。在一个程序中,会声明各种...我们规定内存的生长方向为向上,则的生长方向为向下。压栈的操作push=ESP-4,出栈的操作是pop=ESP+4.换句...
  • java,内存溢出和栈溢出实例

    千次阅读 2017-09-16 16:50:04
    // 如果虚拟机在扩展时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。 --占用的空间太大 public static void main(String[] args) { Main main = new Main(); main.testStackOverflowError(c); // ...
  • 写程序分析栈内存溢出 在Java项目中,有很多时候需要做线程dump,比如,系统挂起、死锁、不能创建更多本地线程的OOME、CPU消耗过多等等;甚至有些堆内存溢出也可能跟线程有关,因为可能是创建了过多的线程导致堆...
  • 涵盖栈深度溢出、永久代内存溢出、本地方法栈溢出、JVM栈内存溢出和堆溢出,让你彻底理解内存溢出!!
  • 内存泄漏并非指内存在物理意义上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 内存泄漏的分类: (1)堆内存泄漏(heap leak):堆内存指的是程序在运行中...
  • 文章目录内存溢出内存泄露内存越界栈溢出 内存溢出 内存泄露 内存越界 栈溢出
  • 因为栈通常是从高地址向低地址增长的,因此"栈溢出"分为两种:超出低地址范围的overrun(上溢)超出高地址范围的underrun(下溢),"上溢"主要是由过深的函数调用引起(比如递归调用):而"下溢"则会出现在数组/字符串...
  • 主要介绍了内存溢出和内存泄漏的详解及区别的相关资料,需要的朋友可以参考下
  • [内存溢出]栈溢出基础版

    千次阅读 2020-12-22 04:45:00
    一、进程使用的内存都可以按照功能大致分为以下4个部分:代码区、数据区、堆区、栈区______________________________________________________________________二、栈溢出ESP: 系统栈最上面一个栈帧的栈顶EBP:系统...
  • 1、 内存溢出的原因是什么? 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查: 一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc...
  • 溢出和栈溢出

    千次阅读 2020-08-26 17:31:08
    jvm堆溢出和栈溢出 一、jvm堆溢出 1、介绍 在jvm运行java程序时,如果程序运行所需要的内存大于系统的堆最大内存(-Xmx),就会出现堆溢出问题。 2、案例 // 介绍:执行该段代码需要大于10m内存空间 public ...
  • 1.栈溢出异常(StackOverflowError) 形成原因: 死循环调用方法。 前几天提了关于栈溢出的一个故障单。微服务A请求微服务B资源的一个方法变成了懒加载,懒加载方法中判断当资源为空时就向微服务C请求资源,请求...
  • 使用 ESP32/ESP8266 进行开发时,读者可通过 vTaskList() 来协助分析操作系统当前 task 状态,以帮助优化内存,帮助定位栈溢出问题,帮助理解学习操作系统原理相关知识。 读者若想深入了解 vTaskList(), 可参考 ...
  • 每个方法在执行的时候都会创建一个栈帧,用来存储局部变量表,操作数,动态链接,方法出口等信息,如果线程所请求的深度大于虚拟机所允许的最大深度,将抛出 StackOverflowError 栈内存溢出异常,一般在方法递归...
  • 堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的,本文将详细介绍Tomcat内存溢出,需要了解更多的朋友可以参考下
  • Java内存溢出栈溢出

    千次阅读 2017-07-20 15:34:06
    http://m.blog.csdn.net/hu1991die/article/details/43052281 一、背景知识 1、JVM体系结构 ...3、JVM内存模型 ...JVM运行时内存 = 共享内存区 + 线程内存
  • JVM之栈溢出和堆溢出

    千次阅读 2021-03-08 09:55:49
    jvm堆溢出和栈溢出一、jvm堆溢出1、介绍在jvm运行java程序时,如果程序运行所需要的内存大于系统的堆最大内存(-Xmx),就会出现堆溢出问题。2、案例//介绍:执行该段代码需要大于10m内存空间public classHeadOverflow ...
  • 为什么要写这个题目?我记得我在面试阿里的时候面试官问了我这个问题,当时没能答得很好...1、如果线程请求的深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常; 2、如果在虚拟机中无法申请到足够...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 132,344
精华内容 52,937
关键字:

内存溢出和栈溢出