精华内容
下载资源
问答
  • Java内存结构

    2014-10-08 16:47:46
    Java内存结构: 深入理解Java内存模型一基础并发编程模型的分类Java内存模型的抽象重排序处理器重排序与内存屏障指令happens-before深入理解Java内存模型二重排序数据依赖性..
  • java内存结构

    2018-11-10 16:13:01
    java内存模型与java内存结构 Java内存模型与Java内存结构是两个不同的概念。当讨论到多线程中,首先想到的是java内存模型(参考我之前的博客java内存模型)。 java内存结构分析 下图为java内存结构。   java堆...

    java内存模型与java内存结构

    Java内存模型与Java内存结构是两个不同的概念。当讨论到多线程中,首先想到的是java内存模型(参考我之前的博客java内存模型)。

    java内存结构分析

    下图为java内存结构。

     

    java堆

    java堆是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例(new 就是在堆里开辟空间),这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。

    java堆是垃圾收集器管理的主要区域,因此也被成为“GC堆”(Garbage Collected Heap)。从内存回收角度来看java堆可分为:新生代和老生代(当然还有更细致的划分,后面在写)。从内存分配的角度看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。无论怎么划分,都与存放内容无关,无论哪个区域,存储的都是对象实例,进一步的划分都是为了更好的回收内存,或者更快的分配内存。

    根据Java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间中。当前主流的虚拟机都是可扩展的(通过 -Xmx 和 -Xms 控制)。如果堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

    java虚拟机栈

    java虚拟机是线程私有的,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的动态内存模型:通常说的堆内存、栈内存中的栈内存指的就是虚拟机栈。

    每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

    局部变量表存放了编译期可知的各种基本数据类型(8个基本数据类型,注意有string类型的)、对象引用(地址指针)、returnAddress类型。

    局部变量表所需的内存空间在编译期间完成分配。在运行期间不会改变局部变量表的大小。

    这个区域规定了两种异常状态:

         1、如果线程请求的栈深度大于虚拟机所允许的深度,则抛出StackOverflowError异常;

         2、如果虚拟机栈可以动态扩展,在扩展是无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    本地方法栈

    本地方法栈与虚拟机栈所发挥作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务。

    本地方法栈也是抛出两个异常。

    方法区

    方法区与java堆一样,是各个线程共享的内存区域。

    它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    它有个别命叫Non-Heap(非堆)。当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常。

    运行时常量区

    运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在加载后进入方法区的运行时常量池中存放。

    调用intern方法就可以把堆内存里的变量变成运行时常量。

    String s1 = "abc";   //字节码常量
    String s2 = "abc";
    
    System.out.println(s1 == s2.intern());//s2.intern()为运行时常量

    程序计数器

    程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。

    程序计数器位于线程独占区。由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。称之为“线程私有”的内存。

    如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined。

    程序计数器内存区域是虚拟机中唯一一个没有规定OutOfMemoryError情况的区域。

    执行引擎

    虚拟机核心的组件就是执行引擎,它负责执行虚拟机的字节码,一般户先进行编译成机器码后执行。

    直接内存

    直接内存不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。但这部分区域是被频繁使用的,而且也可能导致OutOfMemoryError异常。

    在JDK1.4中新加入的NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

    展开全文
  • JAVA内存结构

    2020-07-20 23:09:30
    JAVA内存结构新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义...


    首先说明一点,JAVA内存结构和内存模型是两个不同的概念。
    JAVA内存结构是对JVM管理的内存划分为不同的区域,是JVM运行时的内存区域。
    JAVA内存模型是虚拟机规范定义的用来屏蔽不同的硬件和操作系统的内存访问差异的一种模型,JMM。
    这里记录下对JVM内存结构的一些理解。
    根据Java虚拟机规范,运行时数据区主要分为以下5个部分:程序计数器,Java虚拟机栈,本地方法栈,方法区,堆。

    程序计数器

    程序计数器可理解为PC指针,用来指示当前线程的下一行指令的地址。当然,Java里面应该是字节码的行号指示器。
    每个线程都会有一个程序计数器,是线程私有的。
    如果当前执行的是Java方法,就指向下一行Java方法的地址,如果当前执行的是(本地)Native方法,则值为空。
    程序计数器没有内存溢出的问题。这个不是程序控制的区域。

    Java虚拟机栈

    虚拟机栈里面的存储的是栈帧。
    一个Java方法对应一个栈帧,存放局部变量表、操作数栈、动态链接、方法出口等。
    属于线程私有的内存区域。
    会出现StackOverflow,在动态扩展时,遇到内存不足,会出现OOM。

    本地(Native)方法栈

    同Java虚拟机栈,为Java执行本地方法服务。线程私有。

    堆是Java虚拟机管理的最大的一块内存。
    被所有线程共享,唯一作用就是存放对象。
    “几乎”所有的对象在堆上分配空间。
    堆是垃圾回收器管理的区域。会出现OOM。
    比较经典的HotSpot虚拟机是采用了分代理论设计:新生代,老年代,永久代,新生代又分为Eden区,Survivor区(2个,to和from)。
    可以在启动JVM时设置,通过-Xmx和-Xms设定。(Xmx最大的占用内存量,Xms初始化占用内存量)

    方法区

    存放类的类型信息,常量,静态变量,及时编译以后的代码缓存。
    非堆。
    线程共享。
    会出现OOM。

    运行时常量池

    堆的一部分。
    存放编译期生成的字面量和符号引用。

    直接内存(非JVM规范规定)

    NIO使用Native方法分配堆外内存。
    会出现OOM。

    展开全文
  • java 内存结构

    2017-04-20 10:59:37
    java内存分为:堆、虚拟机栈、本地方法栈、方法区、程序计数器。 程序技术器: 一块较小的内存,可以看做是当前线程所执行的字节码的行号指示器。多线程情况:为了线程切换后能恢复到正确的执行位置,每条...
    java内存分为:堆、虚拟机栈、本地方法栈、方法区、程序计数器

    程序技术器:
    一块较小的内存,可以看做是当前线程所执行的字节码的行号指示器。多线程情况:为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。称这类内存区域为“线程私有”的内存。
    此内存是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

    java虚拟机栈:
    也是线程私有,生命周期与线程相同。描述的是java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口灯信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
    java虚拟机规范,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,但是扩展时无法申请到足够的内存,抛出OutOfMemoryError异常。

    本地方法栈:
    与虚拟机栈作用相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈为虚拟机使用到的Native方法服务。
    同样会抛出StackOverflowError和OutOfMemoryError异常。

    java堆:
    对于大多数应用,java堆是java虚拟机所管理的内存中最大的一块。java堆是被所有线程共享的一块区域,在虚拟机启动时创建。此内存唯一目的是存放对象实例,几乎所有的对象实例都在这里分配内存。
    java堆是垃圾收集器管理的主要区域。从内存回收的角度:java堆可以分为新生代和老生代;在细致一点分为Eden空间、From Survivor空间、To Survivor空间。从内存分配的角度:java堆可以划分出多个线程私有的分配缓冲区。不论如何划分,都与存放内容无关,划分目的是为了更好的回收内存或者更快的分配内存。java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。
    如果堆中没有内存分配实例,并且堆也无法再扩展,抛出OutOfMemoryError异常。

    方法区:
    与堆一样,是多个线程共享的内存区域。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但它有一个别名:非堆。
    java虚拟机对方法区限制非常宽松,不需要连续内存,可以选择固定大小或者可扩展,还可以选择不实现垃圾收集。这块区域的内存回收目标主要是针对常量池的回收和对类型的卸载。而且是必要的。
    当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常。

    来源:《深入理解java虚拟机》

    展开全文
  • 比如本文我们要讨论的JVM内存结构、JAVA内存结构、JAVA内存区域、Java内存模型,这就是几个截然不同的概念,但是很多人容易弄混。 可以这样说,很多高级开发甚至都搞不不清楚JVM内存结构、JAVA内存结构、JAVA内存...

    Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、JAVA内存结构、JAVA内存区域Java内存模型,这就是几个截然不同的概念,但是很多人容易弄混。

    可以这样说,很多高级开发甚至都搞不不清楚JVM内存结构、JAVA内存结构、JAVA内存区域Java内存模型这几个的概念及其间的区别。甚至我见过有些面试官自己也搞的不是太清楚。不信的话,你去网上搜索Java内存模型,还会有很多文章的内容其实介绍的是JVM内存结构。

    前提:

    本文讲的基本都是以Sun HotSpot虚拟机为基础的,Oracle收购了Sun后目前得到了两个【Sun的HotSpot和JRockit(以后可能合并这两个),还有一个是IBM的IBMJVM】

    前一篇文章 编程的基础知识:CPU和内存的交互以及volatile型变量的理解

    之所以扯了那么多计算机内存模型,是因为java内存模型的设定符合了计算机的规范。

    JVM内存结构、Java内存结构、Java内存区域

    这三者都是一个概念

    我们都知道,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。其中有些区域随着虚拟机进程的启动而存在,而有些区域则依赖用户线程的启动和结束而建立和销毁。

    JVM运行时内存结构(也就是咱们常说的运行时数据区)

    五大内存区域

    程序计数器

    程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器。

    为什么需要程序计数器

    我们知道对于一个处理器(如果是多核cpu那就是一核),在一个确定的时刻都只会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可以恢复到正确执行位置,每个线程都需有独立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

    注意:如果线程执行的是个java方法,那么计数器记录虚拟机字节码指令的地址。如果为native【底层方法】,那么计数器为空。这块内存区域是虚拟机规范中唯一没有OutOfMemoryError的区域

    Java栈(虚拟机栈)

    同计数器也为线程私有,生命周期与相同,就是我们平时说的栈,栈描述的是Java方法执行的内存模型

    每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。【栈先进后出,下图栈1先进最后出来】

    对于栈帧的解释参考 Java虚拟机运行时栈帧结构

    栈帧: 是用来存储数据和部分过程结果的数据结构。
    栈帧的位置:  内存 -> 运行时数据区 -> 某个线程对应的虚拟机栈 -> here[在这里]
    栈帧大小确定时间: 编译期确定,不受运行期数据影响。
    

    通常有人将java内存区分为栈和堆,实际上java内存比这复杂,这么区分可能是因为我们最关注,与对象内存分配关系最密切的是这两个。

    平时说的栈一般指局部变量表部分。

    局部变量表:一片连续的内存空间,用来存放方法参数,以及方法内定义的局部变量,存放着编译期间已知的数据类型(八大基本类型和对象引用(reference类型),returnAddress类型。它的最小的局部变量表空间单位为Slot,虚拟机没有指明Slot的大小,但在jvm中,long和double类型数据明确规定为64位,这两个类型占2个Slot,其它基本类型固定占用1个Slot。

    reference类型:与基本类型不同的是它不等同本身,即使是String,内部也是char数组组成,它可能是指向一个对象起始位置指针,也可能指向一个代表对象的句柄或其他与该对象有关的位置。

    returnAddress类型:指向一条字节码指令的地址【深入理解Java虚拟机】怎么理解returnAddress

    需要注意的是,局部变量表所需要的内存空间在编译期完成分配,当进入一个方法时,这个方法在栈中需要分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表大小。

    Java虚拟机栈可能出现两种类型的异常:

    1. 线程请求的栈深度大于虚拟机允许的栈深度,将抛出StackOverflowError。
    2. 虚拟机栈空间可以动态扩展,当动态扩展是无法申请到足够的空间时,抛出OutOfMemory异常。

    本地方法栈

    本地方法栈是与虚拟机栈发挥的作用十分相似,区别是虚拟机栈执行的是Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务,可能底层调用的c或者c++,我们打开jdk安装目录可以看到也有很多用c编写的文件,可能就是native方法所调用的c代码。

    对于大多数应用来说,堆是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。因此需要重点了解下。

    java虚拟机规范对这块的描述是:所有对象实例及数组都要在堆上分配内存,但随着JIT编译器的发展和逃逸分析技术的成熟,这个说法也不是那么绝对,但是大多数情况都是这样的。

    即时编译器:可以把把Java的字节码,包括需要被解释的指令的程序)转换成可以直接发送给处理器的指令的程序)

    逃逸分析:通过逃逸分析来决定某些实例或者变量是否要在堆中进行分配,如果开启了逃逸分析,即可将这些变量直接在栈上进行分配,而非堆上进行分配。这些变量的指针可以被全局所引用,或者其其它线程所引用。

    参考逃逸分析

    注意:它是所有线程共享的,它的目的是存放对象实例。同时它也是GC所管理的主要区域,因此常被称为GC堆,又由于现在收集器常使用分代算法,Java堆中还可以细分为新生代和老年代,再细致点还有Eden(伊甸园)空间之类的不做深究。

    根据虚拟机规范,Java堆可以存在物理上不连续的内存空间,就像磁盘空间只要逻辑是连续的即可。它的内存大小可以设为固定大小,也可以扩展。

    当前主流的虚拟机如HotPot都能按扩展实现(通过设置 -Xmx和-Xms),如果堆中没有内存内存完成实例分配,而且堆无法扩展将报OOM错误(OutOfMemoryError)

    方法区

    方法区同堆一样,是所有线程共享的内存区域,为了区分堆,又被称为非堆。

    用于存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量加载类的时候就被加载到方法区中。

    运行时常量池

    是方法区的一部分,class文件除了有类的字段、接口、方法等描述信息之外,还有常量池用于存放编译期间生成的各种字面量和符号引用。

    在老版jdk,方法区也被称为永久代【因为没有强制要求方法区必须实现垃圾回收,HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。】

    jdk1.7开始逐步去永久代。从String.interns()方法可以看出来 String.interns()

    native方法:

    作用是如果字符串常量池已经包含一个等于这个String对象的字符串,则返回代表池中的这个字符串的String对象,在jdk1.6及以前常量池分配在永久代中。

    可通过 -XX:PermSize和-XX:MaxPermSize限制方法区大小。

    public class StringIntern {
        //运行如下代码探究运行时常量池的位置
        public static void main(String[] args) throws Throwable {
            //用list保持着引用 防止full gc回收常量池
            List<String> list = new ArrayList<String>();
            int i = 0;
            while(true){
                list.add(String.valueOf(i++).intern());
            }
        }
    }
    //如果在jdk1.6环境下运行 同时限制方法区大小 将报OOM后面跟着PermGen space说明方法区OOM,即常量池在永久代
    //如果是jdk1.7或1.8环境下运行 同时限制堆的大小  将报heap space 即常量池在堆中

    idea设置相关内存大小设置

    这边不用全局的方式,设置main方法的vm参数。

    做相关设置,比如说这边设定堆大小。(-Xmx5m -Xms5m -XX:-UseGCOverheadLimit)

    jdk8真正开始废弃永久代,而使用元空间(Metaspace)

    java虚拟机对方法区比较宽松,除了跟堆一样可以不存在连续的内存空间,定义空间和可扩展空间,还可以选择不实现垃圾收集。

    总结

    这里简单提几个需要特别注意的点:

    1、以上是Java虚拟机规范,不同的虚拟机实现会各有不同,但是一般会遵守规范。

    2、规范中定义的方法区,只是一种概念上的区域,并说明了其应该具有什么功能。但是并没有规定这个区域到底应该处于何处。所以,对于不同的虚拟机实现来说,是由一定的自由度的。

    3、不同版本的方法区所处位置不同,上图中划分的是逻辑区域,并不是绝对意义上的物理区域。因为某些版本的JDK中方法区其实是在堆中实现的。

    4、运行时常量池用于存放编译期生成的各种字面量和符号应用。但是,Java语言并不要求常量只有在编译期才能产生。比如在运行期,String.intern也会把新的常量放入池中。

    5、除了以上介绍的JVM运行时内存外,还有一块内存区域可供使用,那就是直接内存。Java虚拟机规范并没有定义这块内存区域,所以他并不由JVM管理,是利用本地方法库直接在堆外申请的内存区域。

    6、堆和栈的数据划分也不是绝对的,如HotSpot的JIT会针对对象分配做相应的优化。

    如上,做个总结,JVM内存结构,由Java虚拟机规范定义。描述的是Java程序执行过程中,由JVM管理的不同数据区域。各个区域有其特定的功能。

    Java内存模型

    Java程序内存的分配是在JVM虚拟机内存分配机制下完成

    Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。

    简要言之,jmm是jvm的一种规范,定义了jvm的内存模型。它屏蔽了各种硬件和操作系统的访问差异,不像c那样直接访问硬件内存,相对安全很多,它的主要目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。可以保证并发编程场景中的原子性、可见性和有序性。

    Java内存模型看上去和Java内存结构(JVM内存结构)差不多,很多人会误以为两者是一回事儿,这也就导致面试过程中经常答非所为。

    在前面的关于JVM的内存结构的图中,我们可以看到,其中Java堆和方法区的区域是多个线程共享的数据区域。也就是说,多个线程可能可以操作保存在堆或者方法区中的同一个数据。这也就是我们常说的“Java的线程间通过共享内存进行通信”。

    Java内存模型是根据英文Java Memory Model(JMM)翻译过来的。其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念。JSR-133: Java Memory Model and Thread Specification中描述了,JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。

    那么,简单总结下,Java的多线程之间是通过共享内存进行通信的,而由于采用共享内存进行通信,在通信过程中会存在一系列如可见性、原子性、顺序性等问题,而JMM就是围绕着多线程通信以及与其相关的一系列特性而建立的模型。JMM定义了一些语法集,这些语法集映射到Java语言中就是volatile、synchronized等关键字。

    在Java中,JMM是一个非常重要的概念,正是由于有了JMM,Java的并发编程才能避免很多问题。这里就不对Java内存模型做更加详细的介绍了,想了解更多的朋友可以参考《Java并发编程的艺术》。

    内存溢出

    两种内存溢出异常[注意内存溢出是error级别的]
    1.StackOverFlowError:当请求的栈深度大于虚拟机所允许的最大深度
    2.OutOfMemoryError:虚拟机在扩展栈时无法申请到足够的内存空间[一般都能设置扩大]
    

    java -verbose:class -version 可以查看刚开始加载的类,可以发现这两个类并不是异常出现的时候才去加载,而是jvm启动的时候就已经加载。这么做的原因是在vm启动过程中我们把类加载起来,并创建几个没有堆栈的对象缓存起来,只需要设置下不同的提示信息即可,当需要抛出特定类型的OutOfMemoryError异常的时候,就直接拿出缓存里的这几个对象就可以了。

    比如说OutOfMemoryError对象,jvm预留出4个对象【固定常量】,这就为什么最多出现4次有堆栈的OutOfMemoryError异常及大部分情况下都将看到没有堆栈的OutOfMemoryError对象的原因。

    参考OutOfMemoryError解读

    两个基本的例子

    public class MemErrorTest {
        public static void main(String[] args) {
            try {
                List<Object> list = new ArrayList<Object>();
                for(;;) {
                    list.add(new Object()); //创建对象速度可能高于jvm回收速度
                }
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }
    
            try {
                //递归造成StackOverflowError 这边因为每运行一个方法将创建一个栈帧,
                //栈帧创建太多无法继续申请到内存扩展
                hi();
            } catch (StackOverflowError e) {
                e.printStackTrace();
            }
    
        }
    
        public static void hi() {
            hi();
        }
    }

     

    参考资料:

    JVM内存结构、Java内存模型以及Java对象模型之间的区别:https://blog.csdn.net/ZYC88888/article/details/83756364

    深入理解JVM-内存模型(jmm)和GC:https://www.jianshu.com/p/76959115d486

    展开全文
  • JAVA内存结构和JAVA内存模型

    千次阅读 2018-01-18 12:01:43
    JAVA内存结构:堆、栈、方法区; 堆:存放所有 new出来的东西(堆空间是所有线程共享,虚拟机气动的时候建立);栈:存放局部变量(线程创建的时候 被创建);方法区:被虚拟机加载的类信息、常量、静态常量等。 类...
  • Java 内存结构

    千次阅读 2014-08-07 12:47:57
    JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程 b) 消亡。当程序中的所有非守护线程都终止时,JVM才退出;若安全管理...
  • Java内存结构

    2020-04-14 09:15:11
    Java内存结构Java内存结构Java内存结构
  • Java内存结构详解相信大多数Javaer对Java的内存结构都有一定的了解,但如果对于Java的内存结构只停留的"堆","栈"中显然是不够的。今天来给大家详细谈一谈Java的内存区域结构,本文基于 JDK7 的内存结构做讲解,JDK8...
  • Java内存结构是每个java程序员必须掌握理解的,这是Java的核心基础,对我们编写代码特别是并发编程时有很大帮助。由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,093
精华内容 9,237
关键字:

java内存结构

java 订阅