美文网首页
关于JAVA栈与堆的讨论

关于JAVA栈与堆的讨论

作者: 木头就是我呀 | 来源:发表于2019-03-03 02:52 被阅读0次

    今天晚上收获颇丰
    详细讨论了java的一些知识

    引入点是 单例多线程 多例单线程

    单例多线程: SpringMVC 的设计
    多例单线程: Struts2 的设计

    单例多线程
    是指 Spring在启动的时候 为 @Controller 注解到的Controller进行对象的创建 而且仅创建这么一份 当有大量用户访问该Controller内的方法的时候 会产生相应数量或者达不到最大值Thread的线程 进行方法的执行 不会再创建Controller对象了 只用当前这个被Spring创建好的对象即可

    多例单线程
    是指 在Struts2 使用的时候 每来到一个用户的请求 就会为该用户请求上下文创建一个对应的Action对象 每个Action对象里面都会有一个值栈对象(只有一个)

    因此在用户量大的时候 Struts2 的模式就会创建大量的对象 对内存的压力比较大 不推荐使用

    接着就谈到了 栈 堆 的问题
    贴上好的帖子:
    https://blog.csdn.net/ns_code/article/details/17565503

    比较重要的一点
    方法区是线程共享的 堆也是线程共享的 栈是线程私有的
    理解:
    共享是相对于私有来讲的
    私有--每个线程会对应一块私有的栈区 每个栈区会对应其内部的栈帧 每个栈帧就是对应的方法
    共享--JVM启动后会且只会产生一个 堆区 所有线程的产生的对象等属于堆的元素都放在这一个大的区域里面 所以叫共享

    而不是我们理解的 线程之间共享

    全局变量(在java中可以理解为用static final修饰):
    在java中全局变量也称成员变量,是创建对象的时候分配内存的。全局常量存于全局数据区。

    具体的概念:
    JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
    堆区:
    1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
    2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
    栈区:
    1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
    2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
    3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
    方法区:
    1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
    2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

    线程的安全与不安全

    造成线程不安全的原因不是多个线程同时执行同一块代码
    因为每个线程都会产生自己私有的 栈区 每个方法又座位栈帧出现在栈区内部 所以不会造成线程之间数据串掉

    真正原因是 访问 全局变量 与 静态变量
    原因:
    全局变量
    存在于堆中 因为堆是共享的 不同线程都从这个大区域内拿值
    当类对象创建之后 会在堆里面创建该全局变量的对象 得到引用
    在使用该全局变量的时候 所有的线程都是使用的这一个 会造成数据混乱 从而造成线程不安全

    静态变量
    存在于方法区中 因为方法区也是共享的 不同线程都是从这个大区域内拿值
    所以会造成数据混乱 从而造成线程的不安全

    相关文章

      网友评论

          本文标题:关于JAVA栈与堆的讨论

          本文链接:https://www.haomeiwen.com/subject/cyiuuqtx.html