精华内容
下载资源
问答
  • JVM五大区域

    2021-05-08 20:34:45
    JVM五大区域 1.程序计数器(Program Counter Register):(PC寄存器即程序计数器 ) 当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支...

    JVM的五大区域

    1.程序计数器(Program Counter Register):(PC寄存器即程序计数器 ) 当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;(私有)

    2.Java 虚拟机栈(栈)(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;(私有)

    3.本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;(私有)

    4.Java堆((堆)Java Heap):Java虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;(共享)

    5.方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量】即时编译后的代码等数据。(共享)

    JVM的内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生、随线程而灭,因此这几个区域的内存分配和回收都具备确定性,就不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟随着回收了。而Java堆区和方法区则不一样这部分内存的分配和回收是动态的,正是垃圾收集器所需关注的部分。

    垃圾收集器在对堆区和方法区进行回收前,首先要确定这些区域的对象哪些可以被回收,哪些暂时还不能回收,这就要用到判断对象是否存活的算法!

    判断对象死没死,常见的有两种方法:


    引用计数法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;


    可达性计数法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。
    在这里插入图片描述

    展开全文
  • jvm 五大内存区域

    2019-04-28 18:08:52
    jvm虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的区域。这些区域各自有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户进程的启动和结束而建立和...

           jvm虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的区域。这些区域各自有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户进程的启动和结束而建立和销毁。

    1.程序计数器

           程序计数器(Program Counter Register)是一块较小的内存空间,可看做当前线程所执行的字节码行号指令器,字节码解释器工作时就是通过改变这个计数器的值来选择下一条需要执行的字节码指令。

    • 线程私有。每个线程都需要一个独立的程序计数器,个线程之间计数器互不影响,独立存储
    • 如果线程正在执行的是一个java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是native方法,则这个计数器为空。
    • 此内存区域是唯一一个在java虚拟机中没有规定 Out Of Memory Error情况的区域。

    2.虚拟机栈

           虚拟机栈(Java Virtual Machine Stacks)描述的是java方法(也就是字节码)执行的内存模型:每个方法在执行的时候都有一个栈帧(Stack Frame),用于存储局部变量表(存放编译器可知的基本数据类型和对象引用),操作数栈,动态链接,方法出口等信息。每一个方法从调用到执行就对应了一个栈帧在虚拟机栈中入栈到出栈的过程。

    • 线程私有。生命周期与线程相同。
    • 在java虚拟机规范中,这个区域规定了两种异常状况。一是 Stack Overflow Error 异常,表示当前线程请求的栈深度大于虚拟机所允许的深度;二是Out Of Memory Error 如果所在虚拟机可以扩展,当它扩展时无法得到足够的内存,则会抛出该异常。

    3.本地方法栈

           本地方法栈(Native Method Stack)与虚拟机栈发挥的作用是相似的,不同点在于虚拟机栈执行的是java方法服务,而本地方法栈是为虚拟机使用到的Native方法服务。有的虚拟机直接把虚拟机栈和本地方法栈合二为一,与虚拟机栈一样,本地方法栈也会抛出Stack Overflow Error和Out Of Memory Error异常。

    4.java堆

           java堆是java虚拟机所管理的内存中最大的一块。它用来存放对象实例和数组。

    • 线程共享。java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。
    • java堆是垃圾收集器管理的主要区域,因此很多时候也被称作 “GC堆”(Garbage Collection Heap)。
    • java堆可以处于物理不连续的内存空间中,只要逻辑上连续即可。
    • 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,则会抛出Out Of Memory Error 。

    5.方法区

         方法区与java堆一样,是线程共享的区域,它里面存储已被虚拟机加载的类信息、静态变量、常量等数据。当方法区无法满足内存分配需求时,会抛出Out Of Memory Error 。运行时常量池是方法区的一部分,用来存放编译器生成的各种字面量和符号的引用。

     

    展开全文
  • JVM五大内存区域介绍

    千次阅读 2019-07-11 11:40:21
    1、程序计数器 ...这块内存区域是虚拟机规范中唯一没有OutOfMemoryError的区域。 2、Java栈(虚拟机栈) 栈描述的是Java方法执行的内存模型。 每个方法被执行的时候都会创建一个栈帧用于存储...

    1、程序计数器

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

      那么计数器记录虚拟机字节码指令的地址。如果为native【底层方法】,那么计数器为空。

     这块内存区域是虚拟机规范中唯一没有OutOfMemoryError的区域。

    2、Java栈(虚拟机栈)

    栈描述的是Java方法执行的内存模型。

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

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

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

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

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

    3、本地方法栈

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

    4、堆

    堆是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。

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

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

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

    堆是所有线程共享的,它的目的是存放对象实例。同时它也是GC所管理的主要区域,因此常被称为GC堆,又由于现在收集器常使用分代算法,Java堆中还可以细分为新生代和老年代。

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

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

    5、方法区

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

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

    在老版jdk,方法区也被称为永久代。

    不过自从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 即常量池在堆中

     

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

    此部分借鉴与简书,作者Garwer所注内容

     

    展开全文
  • JVM规范中的五大java内存区域

    万次阅读 多人点赞 2016-03-31 16:07:53
    JVM在执行java程序时会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。有的数据区域随着JVM的进程而启动,有的数据区域则依赖于用户线程的启动和结束而创建和销毁

    JVM在执行java程序时会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间。有的数据区域随着JVM的进程而启动,有的数据区域则依赖于用户线程的启动和结束而创建和销毁。

    根据Java虚拟机规范规定,Java虚拟机所管理的内存将会包括如下几个运行时数据区域。

    这里写图片描述

    1.程序计数器( Program Counter Register)

    程序计数器( Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。该区域是属于线程私有的,因为在多线程环境中CPU通过在不同的线程来高速切换,此时程序计数器需要记录当前线程执行到哪一步了,以便下一次CPU可以在这个记录点上继续执行。
    此内存区域是唯一一个在Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。

    2..Java 虚拟机栈( Java Virtual Machine Stacks)

    线程私有的,它的生命周期与线程相同。虚拟机栈描述的是 Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧( Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
    局部变量表存放了编译期可知的8种基本数据类型.对象引用( reference 类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和 returnAddress 类型(指向了一条字节码指令的地址) 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
    如果线程请求的栈深度大于虚拟机所允许的深度,将抛出 StackOverflowError 异常
    如果虚拟机栈扩展时无法申请到足够的内存时会抛出 OutOfMemoryError 异常。

    3.本地方法栈( Native Method Stacks)

    与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的 Native方法服务。有的虚拟机(譬如 Sun HotSpot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一。

    4.Java 堆( Java Heap)

    Java堆是 Java 虚拟机所管理的内存中最大的一块。 Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆( ” Garbage Collected Heap)。如果从内存回收的角度看,Java堆又会划分为好几个区域(新时代,老年代,等等)如果从内存分配的角度看,线程共享的 Java 堆中可能划分出多个线程私有的分配缓冲区。但无论怎么去划分,无论那个区域,java堆中存储的依然是对象的实例。进一步划分的目的是为了更好地回收内存,或者更快地分配内存。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出 OutOfMemoryError 异常。

    5.方法区( Method Area)

    与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。*HotSpot 虚拟机上很多人愿意把方法区称为“永久代”( Permanent Generation),本质上两者并不等价,仅仅是因为 HotSpot 虚拟机的设计团队选择把GC 分代收集扩展至方法区,或者说使用永久代来实现方法区而已。对于其他虚拟机(如 BEA JRockit、IBM J9 等)来说是不存在永久代的概念的。即使是 HotSpot 虚拟机本身,根据官方发布的路线图信息,现在也有放弃永久代并“搬家”至 Native Memory 来实现方法区的规划了。此区域还可以选择不实现垃圾收集。相对而言,垃圾收集行为在这个区域是比较少出现的,但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载.在JDK1.7的HotSpot中,把原本放在永久代中的字符串常量池移出了。*

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

    非JVM规范的内存区域:直接内存

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

    在JDK1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式。它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场合中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

    《深入理解java虚拟机 JVM高级特性与最佳实践》周志明

    展开全文
  • JVM五大内存区域

    千次阅读 2017-03-28 13:56:02
    JVM五大内存区域虚拟机栈这是线程私有的,生命周期与线程相同,存储局部变量,动态链接,方法,操作栈等如果栈操作深度大于虚拟机所允许的深度,将抛出stackOverFlowError如果栈申请不到足够的内存,将抛出outOf...
  • JVM-五大

    万次阅读 多人点赞 2018-05-24 20:50:50
    谈一谈Java内存区域的划分实际上是指JVM内存区域的划分,首先Java先介绍一下Java程序具体执行的过程 如上图所示,首先Java源代码们(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器...
  • JVM五大分区

    千次阅读 2018-12-26 18:49:12
    由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此在任一时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都...
  •   JVM是Java Virtual Machine的缩写,即咱们经常提到的Java虚拟机。虚拟机是一种抽象化的计算机,有着自己完善的硬件架构,如处理器、堆栈等,具体有什么咱们不做了解。目前我们只需要知道想要运行Java文件,必须...
  • JVM五大分区

    2020-04-09 13:42:35
    五大分区是jvm运行时的数据区,是描述类加载时,经过解析储存到特定的数据区。先说五大分区分别是:程序计数器、虚拟机栈、本地方法栈、堆、方法区;其中前三个区是线程私有的,用来处理程序允许时的问题;后两个区...
  • Java虚拟机运行时数据区域:https://blog.csdn.net/StrideBin/article/details/73530331
  • Java运行时数据区: 我们可以看到Java虚拟机在执行Java程序的时候,将Java的内存可以分为若干个区域方法区(Method Area) 、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack) 、堆(Heap) 、程序计数器...
  • jvm

    千次阅读 2018-07-23 17:09:05
    三种JVM  Sun公司的HotSpot;  BEA公司的JRockit;  IBM公司的J9 JVM;  在JDK1.7及其以前我们所使用的都是Sun公司的HotSpot,但由于Sun公司和BEA公司都被oracle收购,jdk1.8将采用Sun公司的HotSpot和BEA公司的...
  • JVM内存模型-五大区浅解

    千次阅读 2018-06-16 10:22:01
    JVM五大区 一、程序计数器程序计数器( Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要...
  • 主要介绍以下内容: Java虚拟机内存的各个区域, 这些区域的作用, 服务对象以及其中可能产生的问题运行时数据区域概览图程序计数器(Program Counter Register)可以看做当前线程所执行的字节码的行号指示器. 在多线程...
  • JVM内存模型,主要包含区域。其中线程共享:方法区和堆,线程私有:虚拟机栈、本地方法栈和程序计数器 方法区 方法区是用来存储被Java虚拟机加载的类信息,常量,静态变量,运行时常量池等。在jdk8以前,方法区...
  • JVM这个话题是面试的时候经常问到一个难点,今天将会从...今天的问题是,从内存角度看,哪些区域会产生OutOfMemoryError 概述 通常会将JVM内存划分为几个方面: 第一,程序计数器(PC)。在JVM中,每个线程都有自己...
  • JVM 规范中,每个线程都有它自己的程序计数器,并且任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的 Java 方法的 JVM 指令地址;或者,如果是在执行本地方法,...
  • JVM各内存区域存放内容

    千次阅读 2018-10-04 11:33:18
    一、方法区存放内容: 1.类的全限定名(类的全路径名)。 2.类的直接超类的权全限定名(如果这个类是Object,则它没有超类)。 3.类的类型(类或接口)。...当jvm使用类装载器装在某个类时,它首先要定位到对应的...
  • JVM(一)–JVM的内存区域划分以及相关知识点 一、JVM的内存区域是怎么划分的? JVM结构图 JVM = 类加载器 + 执行引擎 + 运行时数据区 类加载器(Class Loader):把硬盘上的class文件加载到JVM中的运行时数据区域,...
  • 五大内存区域:堆、栈、方法区、本地方法栈、程序计数器 1.堆:用来存放类对象 成员变量的地方,线程共享。 简单来说 例如:new People() 这个对象 就放在堆里面。 2.栈:与堆相对应的,存放局部变量,基本类型变量...
  • JVM内存区域

    2020-07-26 18:42:16
    JVM的学习分两个阶段即...2、JVM内存区域:同理JVM内存区域也就是java程序运行时读取、存放相关数据的区域。 3、JVM内存模型:在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。 其实JVM内存区.
  • jvm(一)——内存区域划分

    千次阅读 2018-08-31 19:29:16
    前言:jvm内存划分为多个区域,每个不同的区域分别有着不同的功能和不同的用途,本篇博客旨在说清楚区域的划分、名称、属性以及作用,本篇博客是参考了多篇博客的结果,参考博客会在文章结尾进行说明。 上图中...
  • JVM内存区域划分及其作用

    千次阅读 2018-06-21 21:34:26
    让线程轮流切换各条线程之间计数器互不影响线程私有,生命周期与线程相同,随JVM启动而生,JVM关闭而死线程执行Java方法时,记录其正在执行的虚拟机字节码指令地址线程执行Nativan方法时,计数器记录为空(Undefined...
  • JVM的内存区域划分(jdk7和jdk8)

    万次阅读 多人点赞 2018-08-08 11:58:29
    1、什么是JVM 2、JRE/JDK/JVM是什么关系 3、JVM执行程序的过程 4、 JVM的生命周期 5、JVM垃圾回收 一.运行时数据区的组成 1.程序计数器 2.Java栈(虚拟机栈) 1)、局部变量表 2)、操作数栈 3)、指向...
  • 通常可以把 JVM 内存区域分为下面几个方面,其中,有的区域是以线程为单位,而有的区域则是整个 JVM 进程唯一的。 第一,程序计数器(PC,Program Counter Register)。在 JVM 规范中,每个线程都有它自己的程序...
  • JVM内存区域划分

    2019-11-07 11:38:04
    其中JVM的内存区域一般分为:堆(heap),虚拟机栈(VM stack),本地方法栈(Native Method Stack),方法区(Method Area),程序计数器(Program Counter Register)五大区域。每个区域都有其特性,会影响内存...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    文章目录Java概述何为编程什么是Javajdk1.5之后的三版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些特点什么是字节码?采用字节码的最大好处是什么什么是Java程序的主类?应用程序和小程序的...
  • 原文出处: 海 子 ...由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 如上图所示,

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,411
精华内容 12,964
关键字:

jvm五大区域