• uyong
    2019-03-23
    栈溢出原因:
    因为每调用一个方法就会在栈上创建一个栈帧,方法调用结束后就会弹出该栈帧,而栈的大小不是无限的,所以递归调用次数过多的话就会导致栈溢出。而递归调用的特点是每递归一次,就要创建一个新的栈帧,而且还要保留之前的环境(栈帧),直到遇到结束条件。所以递归调用一定要明确好结束条件,不要出现死循环,而且要避免栈太深。
    解决方法:
    1. 简单粗暴,不要使用递归,使用循环替代。缺点:代码逻辑不够清晰;
    2. 限制递归次数;
    3. 使用尾递归,尾递归是指在方法返回时只调用自己本身,且不能包含表达式。编译器或解释器会把尾递归做优化,使递归方法不论调用多少次,都只占用一个栈帧,所以不会出现栈溢出。然鹅,Java没有尾递归优化。
    展开

    作者回复: 很全面了。所有的递归算法都可以用非递归算法实现,大学老师好像还出过这样一道题......

     2
     98
  • suynan
    2019-03-25
    对于这句话:“ new 出来的对象是在堆里,局部变量在栈里”
    我觉得应该是对象在堆里,引用(句柄)在栈里

    作者回复: 是的

     2
     21
  • Kǎfκã²⁰²⁰
    2019-03-23
    因为调用方法时局部变量会进线程的栈帧,线程的栈内存是有限的,而递归没控制好容易造成太多层次调用,最终栈溢出。

    解决思路一是开源节流,即减少多余的局部变量或扩大栈内存大小设置,减少调用层次涉及具体业务逻辑,优化空间有限;二是改弦更张,即想办法消除递归,比如说能否改造成尾递归(Java会优化掉尾递归)

    作者回复: 没怎么听说Java尾递归优化的事情,不太确定。最好不要依赖这个

    
     20
  • Xiao
    2019-03-27
    如果方法内部又有多线程,那方法内部的局部变量是不是也不是线程安全。

    作者回复: 你看看编译器允不允许这样做吧

     3
     9
  • Geek_cc0a3b
    2019-03-24
    new 出来的对象是在堆里,局部变量是在栈里,那方法中new出来的对象属于局部变量,是保存在堆里还是在栈里呢?

    作者回复: 对象堆里,但是指针在栈里

    
     9
  • bing
    2019-03-23
    当遇到递归时,可能出现栈空间不足,出现栈溢出,再申请资源扩大栈空间,如果空间还是不足会出现内存溢出oom。
    合理的设置栈空间大小;
    写递归方法注意判断层次;
    能用递归的地方大多数能改写成非递归方式。

    作者回复: 全面!

    
     9
  • ack
    2019-03-23
    如果是jvm栈空间太小了导致的栈溢出,可以通过-Xss增大栈空间大小。并且递归方法一定要有终止的return条件
    
     7
  • crudBoy
    2019-05-09
    其实就是并发调用方法而产生的局部变量指向的内存地址都是不同的。 所以同一时刻只会有一个线程去操作这些局部变量指向的内存。
    
     5
  • 锦
    2019-04-19
    老师我有个问题:有一个方法的参数是引用类型,方法内定义了一个局部变量,在方法内将引用类型的参数赋值给该局部变量,然后再操作该局部变量会不会存在线程安全问题?比如:
    void test(account a){
        account b = a;
        b.addMoney(100);
    }

    作者回复: 存在

     2
     4
  • 卡西米
    2019-03-23
    请教一个问题JAVA的栈跟cpu的栈有什么关系?

    作者回复: 没关系,只是原理类似

    
     3
  • 闲人
    2019-12-12
    老师,有两个疑问求解答:
    1.程序计数器和CPU栈寄存器是一回事吗?
    2.线程切换会导致CPU堆栈寄存器来回刷新吗?

    作者回复: 1. 不是一回事
    2. 会

    
     2
  • 风过无痕
    2019-07-15
    CPU 的堆栈寄存器和栈帧什么关系 老师 求你回答一下我一个问题吧 我的问题你都没回答过

    作者回复: 堆栈寄存器指向栈顶内存地址

    
     2
  • 杨鹏程baci
    2019-06-28
    老师好,我理解一下,您绿的例子里面线程池获取一个线程在方法体里面赋给了一个局部变量,但是从线程池获取线程的过程还是要用到锁吧,只是后面这个线程也不会被重复分配了,所以不需要加锁
    
     2
  • Tuberose
    2019-03-25
    还有一点就是 静态方法是否是线程安全的?j

    作者回复: 不安全

    
     2
  • 文兄
    2019-12-06
    局部变量是线程安全的
    对于这句话我的理解是,在方法内创建的变量是线程安全的
    那么方法的入参,是否是线程安全的呢
    方法的入参是对象的情况下还是否是线程安全的呢

    希望有大手子答疑
    展开

    作者回复: 粗略的结论是,引用传递不安全,值传递安全

    
     1
  • Thong2018
    2019-08-26
    看老师讲Java并发编程的知识,让我明白了很多之前在大学里没有学明白的知识点。要是大学的专业课本也能像老师这样讲得通俗易懂而又不失深度就好了,用“大道至简”来形容老师的授课风格再好不过了

    作者回复: 过奖了😄

    
     1
  • 000
    2019-07-03
    每次递归就创建一个栈桢,没控制好结束,会导致栈空间溢出
    
     1
  • 锦
    2019-04-19
    递归函数中的递会调用函数,递归的太深可能会引起栈溢出;
    解决方案:
    1、限制递归深度,超过则退出,缺点是不能确定栈的剩余空间;
    2、使用hashmap保存重复子问题的值,以减少递归次数;
    
     1
  • JensonYao
    2019-04-19
    非常形象的解释了堆和栈的区别,又带着复习了一遍基础知识,每一次看都有不一样的认知!谢谢老师!

    作者回复: 你有收获也是对我最大的鼓励😃

    
     1
  • 非礼勿言-非礼勿听-...
    2019-03-30
    递归可能导致栈溢出,基本上都知道原因,这里说下个人对于如何避免的浅见:
    1.递归基本上都可改写成循环方式
    2.限制递归层次
    3.其实和1是一个道理,模拟栈结构
    
     1
我们在线,来聊聊吧