• 3 栈


    那我们java中每个线程运行的时候需不需要为每个线程划分独立的空间呢?

    • 答案肯定是的。我们的虚拟机栈呢就是线程运行时需要的空间,一个线程需要一个栈。

    那栈内组成元素又是什么呢?

    • 栈帧

    栈帧又代表什么呢?

    • 那大家想,我的线程他最终是要去执行代码的。那这些代码呢都是由一个个的方法来组成的。所以线程运行的时候,每个方法他运行时需要的内存,我们就称之为一个栈帧。

    那大家想,我方法需要什么内存啊?方法里面的参数,变量不都得需要内存吗。每个方法调用完了,他还需要一个返回地址,那这些信息都是需要占用内存的。所以每个方法执行时,我们就需要预先把这些内存给他分配好。

    我方法在执行的时候,就会把对应的栈帧压进栈。当方法执行完之后,再把栈帧出栈。也就是释放这个方法所占用的内存。

    那有没有可能一个栈内有多个栈帧存在呢?

    • 有的,假如我调用方法1,这一个栈帧,然后方法1间接调用其它方法,这又是一个栈帧

    那方法三调用结束就把栈帧3出栈,回到方法2,方法2调用结束之后栈帧2出栈,回到方法1。

    3.1 栈的演示

    java virtural machine stacjs(java虚拟机栈)

    • 每个线程运行时所需的内存,称为虚拟机栈

    • 每个栈由多个栈帧(frame)组成,对应着每次方法调用时所占用的内存

    • 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法。

    往下执行

    再往下

    再往下:

    继续往下执行

    3.2 栈问题辨析1

    1:垃圾回收是否涉及栈内存?

    • 栈内存在方法调用的时候产生,方法调用结束就销毁掉了,不需要垃圾回收来解决。

    2:栈内存分配越大越好吗?

    • 栈内存我们指定大小 -Xss size 

    • 栈内存划的大,反而会让你的线程数变少。因为我们物理内存的大小是一定的。比如说我一个线程使用的是占内存1M,总内存是500M。理论上线程可以有500个。但是如果你每个线程的内存设置为2M,那线程数就只有250个。

    3:方法内的局部变量是否是线程安全的?

    • 那看变量安全不安全,我们就看这个变量他对多个线程来说是共享的还是每个线程私有的。我们看一段代码来解释这个问题。image-20210917211619917

      假如有两个线程同时来执行这个方法,那会不会造成这个方法里面的x混乱呢?

      • 不会,因为我们x变量是方法内的局部变量,我们说一个线程对应一个栈帧。那这两个线程的栈帧是不一样的,相当于每个线程都有自己私有的局部变量x,互不影响。

    那假如把x改为静态的呢?

    • 这个时候因为是静态的,那么两个线程都会去操作这个变量,并且操作完之后还会把结果返回,那就会造成混乱,最后的结果可能不是5000.

    3.3 栈问题辨析3

    你要看一个变量是不是线程安全的,你不能仅仅看她是不是局部变量,还得看他是不是逃离了我这个方法的作用范围。

    例1:

    虽然说sb是在方法内部,是局部变量,但是他被作为返回结果返回了,逃离了我这个线程的作用范围。那其他线程就有可能拿到这个变量,去并发的修改他。就不是线程安全的。如果

    3.4 栈-内存溢出

    什么情况会导致栈内存溢出?

    • 栈帧过多导致栈内存溢出。(递归调用的时候没有设置结束条件)

      思考补充:为什么这里用exception 就打印不出结果,而用throwable就可以打出结果?

    • 当json转换格式的时候里面数据互相调用死循环导致栈溢出

    • 栈帧过大导致栈帧内存溢出。(不太容易出现这种情况)

     

    如何避免去写栈内存溢出的代码?

    3.5 线程诊断

    案例1:cpu占用过多

    定位:

    • 用top命令定位哪个进程对cpu占用过高

    • ps H -eo pid, tid % cpu | grep 进程id (用ps进一步查看是哪个线程干的好事)

    • jstack 进程id (查看进程中的线程,注意jstack输出的进程编号是16进制的)

      • 可以根据线程id找到线程,进一步定位到有问题的源码行数

     

    案例二:程序运行很长时间没有结果

    • 线程之间发生死锁

  • 相关阅读:
    Jedis入门
    redis的安装
    redis概述
    020 SpringMVC返回Json
    019 数据绑定流程分析(校验)
    018 数据绑定流程分析(包括数据转换与格式化)
    maven添加插件,与maven打包
    定制库到maven库
    maven仓库
    Maven启动代理访问
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/15332736.html
Copyright © 2020-2023  润新知