精华内容
下载资源
问答
  • JVM运行时数据区 线程共享部分 一 、 方法区 方法区就是JVM用来存储类信息、常量、静态变量、编译后的代码等数据的。 虚拟机规范中这是一个逻辑区划,具体根据不同的操作系统来实现的。 二、 堆内存 堆内存可以细分...

    JVM运行时数据区

    线程共享部分

    一 、 方法区

    方法区就是JVM用来存储类信息、常量、静态变量、编译后的代码等数据的。
    虚拟机规范中这是一个逻辑区划,具体根据不同的操作系统来实现的。
    

    二、 堆内存

    堆内存可以细分为:老年代、新生代
    JVM启动时创建,用来存放实例对象的。垃圾回收器主要就是管理这块区域
    

    线程独占部分

    一、虚拟机栈

    每个线程都有一个私有的空间
    线程栈由多个栈帧组成。
    一个线程会执行一个或者多个方法,一个方法对应一个栈帧。
    栈帧内容包括:局部变量表、操作数栈、动态连接、方法返回地址、附加信息等。
    栈内存默认最大为1M,超出则抛StackOverflowError.
    

    二、 本地方法栈

    和虚拟机栈类似,虚拟机栈是为了虚拟机执行Java代码准备的。而本地方法栈则是为了虚拟机执行本地方法(native)准备的。
    虚拟机规范没有规定具体的实现,由不同的虚拟机厂家实现。
    

    三、 程序计数器

    程序计数器记录当前线程执行的字节码的位置。存储的是字节码指令地址,如果执行Native方法,则计数器为空
    每个线程都在这个空间有一个私有的空间,占用的空间很小。
    CPU同一时间只能执行一条线程中的指令, 当线程切换的时候,通过程序计数器来恢复正确的执行位置。
    

    什么是线程共享,什么是线程独占部分呢?

    1. 线程独占: 每个线程都会有它独立的空间,随着线程的生命周期而创建和销毁

    2. 线程共享: 所有线程都能访问这块内存的数据,随着虚拟机或者GC而创建和销毁。

    展开全文
  • 鉴于面试,针对该问题没有回答好...如图,存在:堆,栈(又名线程栈,虚拟机栈),本地方法栈,方法区(1.8存储在本地内存中,又称元数据区),程序计数器五个部分组成。 各部分的作用不做详解,需要者自行百度 ...

    鉴于面试时,针对该问题没有回答好,特此记录下
    在这里插入图片描述
    如图,存在:堆,栈(又名线程栈,虚拟机栈),本地方法栈,方法区(1.8存储在本地内存中,又称元数据区),程序计数器五个部分组成。
    各部分的作用不做详解,需要者自行百度

    展开全文
  • JVM运行时数据区总结

    2021-02-03 15:18:58
    JVM运行时数据区总结 JVM简述 运行时数据区 1. JVM内存模型,有哪些区,分别的作用 方法区 方法区是用来存储被Java虚拟机加载的类信息,常量,静态变量,运行时常量池等。在jdk8以前,方法区中定义了永久代...

    JVM运行时数据区总结

    • JVM简述
      在这里插入图片描述

    • 运行时数据区

    在这里插入图片描述

    1. JVM内存模型,有哪些区,分别的作用

    img

    方法区

    方法区是用来存储被Java虚拟机加载的类信息,常量,静态变量,运行时常量池等。在jdk8以前,方法区中定义了永久代。因为使用永久代来实现了方法区,所以被描述为堆的一个逻辑部分。但是它确是“非堆”,只是设计堆中的收集器 扩展到了方法区而已。在jdk8的时候,永久代被替换成了元空间(Metaspace)。这样做的好处有以下原因

    • Metaspace使用的是本地内存
    • 字符串常量池存在永久代中,容易出现性能问题和内存溢出。
    • 类和方法的信息难以确定,给永久代指定大小比较困难,太小容易操作永久代溢出,太大会导致老年代溢出。
    • 永久代会为GC带来不必要的复杂性。

    java堆

    img

    Java堆在JVM中是一块最大的内存,用于存储对象实例及数组值,可以认为Java中所有通过new创建的对象的内存都在此分配,堆区由所有线程共享。如上图所示,在堆上划分了很多区域,新生代、老年代和永久代。其中新生代又划分为了一个eden区和两个survivor区。Java堆实际上是垃圾收集器(GC)管理的一块内存区域,经过之上的划分得以进行更有效率的垃圾回收。

    虚拟机栈

    Java虚拟机栈是线程私有的,每个线程都对应着一个虚拟机栈。每个方法执行的时候都会创建一个栈帧,它是方法运行时的基础数据结构。栈帧中主要存储的有局部变量表、操作数栈、动态链接、方法出口等,当方法被调用时,栈帧在JVM栈中入栈,当方法执行完成时,栈帧出栈。虚拟机栈中定义了两种异常,如果线程调用的栈深度大于虚拟机允许的最大深度,则抛出StatckOverFlowError(栈溢出);不过多数Java虚拟机都允许动态扩展虚拟机栈的大小(有少部分是固定长度的),所以线程可以一直申请栈,直到内存不足,此时,会抛出OutOfMemoryError(内存溢出)。

    本地方法栈

    本地方法栈和虚拟机栈类似,JVM并未要求本地方法栈一定实现某种语言的方法调用,使用者可以灵活去进行调用。用于支持native方法的执行,存储了每个native方法调用的状态。本地方法栈和虚拟机方法栈运行机制一致,它们唯一的区别就是,虚拟机栈是执行Java方法的,而本地方法栈是用来执行native方法的,在很多虚拟机中,会将本地方法栈与虚拟机栈放在一起使用。

    程序计数器

    程序计数器是一个比较小的内存区域,可能是CPU寄存器或者操作系统内存,其主要用于指示当前线程所执行的字节码执行到了第几行,可以理解为是当前线程的行号指示器。字节码解释器在工作时,会通过改变这个计数器的值来取下一条语句指令。 每个程序计数器只用来记录一个线程的行号,所以它是线程私有(一个线程就有一个程序计数器)的。
    如果程序执行的是一个Java方法,则计数器记录的是正在执行的虚拟机字节码指令地址;如果正在执行的是一个本地(native,由C语言编写完成)方法,则计数器的值为Undefined,由于程序计数器只是记录当前指令地址,所以不存在内存溢出的情况,因此,程序计数器也是所有JVM内存区域中唯一一个没有定义OutOfMemoryError的区域

    2.Java8的内存分代改进

    无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆

    方法区的演进细节
        
    首先明确:只有HotSpot才有永久代。
    BEA JRockit、IBM J9等来说,是不存在永久代的概念的。原则上如何实现方法区属于虛拟机实现细节,不受《Java虚拟机规范》管束,并不要求统一。
    Hotspot中 方法区的变化:
    jdk1.6及之前:有永久代(permanent generation) ,静态变量存放在
    永久代上
    jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池、静态变量移除,保存在堆中
    jdk1.8及之后: 无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍在堆
    
    永久代为什么要被元空间替换
    
    随着Java8的到来,HotSpot VM中再也见不到永久代了。但是这并不意味着类.的元数据信息也消失了。这些数据被移到了一个与堆不相连的本地内存区域,这个区域叫做元空间( Metaspace )。
    由于类的元数据分配在本地内存中,元空间的最大可分配空间就是系统可用内存空间。
    这项改动是很有必要的,原因有:
    
    1)为永久代设置空间大小是很难确定的。
    在某些场景下,如果动态加载类过多,容易产生Perm区的O0M。比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误。
    "Exception in thread' dubbo client x.x connector’java.lang.OutOfMemoryError: PermGenspace"
    而元空间和永久代之间最大的区别在于:==元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制==2)对永久代进行调优是很困难的。
    
    
    
    StringTable 为什么要调整
    jdk7中将StringTable放到了堆空间中。因为永久代的回收效率很低,在full
    gc的时候才会触发。而full GC 是老年代的空间不足、永久代不足时才会触发。这就导致了StringTable回收效率不高。而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足。放到堆里,能及时回收内存.
    

    3.Jvm运行时数据区对象什么时候进入老年区

    • 对象年龄达到老年代标准,默认为15

    • 大对象(大小在2KB~128KB),在经过MinorGC后Eden仍然没有足够空间存放,这直接进入老年区

      new的对象先放伊甸园区。此区有大小限制。
      当伊甸园的空间填满时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区
      然后将伊甸园中的剩余对象移动到幸存者0区。
      如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有回收,就会放到幸存者1区。
      如果再次经历垃圾回收,此时会重新放回幸存者0区,接着再去幸存者1区。
      啥时候能去养老区呢?可以设置次数。默认是15次。·可以设置参数:-XX:MaxTenuringThreshold=进行设置。
      在养老区,相对悠闲。当老年区内存不足时,再次触发GC:Major GC,进行养老区的内存清理。
      若养老区执行了Major GC之后发现依然无法进行对象的保存,就会产生OOM异常
      

    4.为什么要有新生代和老年代? 新生代中为什么要分为Eden和Survivor?为什么要有两个survivor区?

    主要是为了优化GC性能
    不同对象的生命周期不同。绝大多数的对象是临时对象。

    • 因为有的对象寿命长,有的对象寿命短。应该将寿命长的对象放在一个区,寿命短的对象放在一个区。不同的区采用不同的垃圾收集算法。寿命短的区清理频次高一点,寿命长的区清理频次低一点。提高效率。

    如果没有Survivor区,那么Eden每次满了清理垃圾,存活的对象被迁移到老年区,老年区满了,就会触发Full GC,Full GC是非常耗时的,解决办法:

    • 增加老年代内存,那么老年代清理频次减少,但清理一次花费时间更长。

    • 减少老年代内存,老年代一次FullGC时间更少,频率增加。

    都不行,只有再加一层Survivor。将Eden区满了的对象,添加到Survivor区,等对象反复清理几遍之后都没清理掉,再放到老年区,这样老年区的压力就会小很多。即Survivor相当于一个筛子,筛掉生命周期短的,将生命周期长的放到老年代区,减少老年代被清理的次数

    先来看一下一个的
    在这里插入图片描述
    清理内存,很容易产生内存碎片,为了不产生内存碎片,我才用复制算法,将Eden区和Survivor区存活的对象整齐的放到一个空的内存。因为生命周期一般都比较短,所以在存活对象不多的情况下,复制算法效率还是比较高的。

    复制算法
    在这里插入图片描述
    这样就需要一个空内存,而我如果有三个区,这样就总可以保持一个是空的,这样我清理垃圾的时候,就可以将存活对象全部都整齐的放到一个空的内存中,不产生内存碎片了。

    5.堆和栈的的区别? 堆的结构?

    Java把内存分为栈内存和堆内存。两者的主要区别是:

    • 栈是线程私有,堆是被线程共享的内存区域

    • 作用:虚拟机栈用来描述java执行过程,堆用来存储运行过程中创建的对象和产生的数据

    • 回收:栈只有入栈和出栈没有回收机制,堆有垃圾回收机制

    堆的结构:

    • JDK 7以前: 新生区+养老区+永久区(逻辑上,事实非堆)

    • JDK 8以后: 新生区+养老区+元空间

    6.Jvm的永久代中会发生垃圾回收吗?

    会 ,《Java 虚拟机规范》对方法区的约束是非常宽松的,提到过可以不要求虚拟机在方法区中实现垃圾收集。事实上也确实有未实现或未能完整实现方法区类型卸载的收集器存在(如 JDK11 时期的 2GC 收集器就不支持类卸载)。
     一般来说这个区域的回收效果比较难令人满意,尤其是类型的卸载,条件相当苛刻。但是这部分区域的回收有时又确实是必要的。以前 Sun 公司的 Bug 列表中,曾出现过的若干个严重的 Bug 就是由于低版本的 Hotspot 虚拟机对此区域未完全回收而导致内存泄漏。
     方法区的垃圾收集主要回收两部分内容:常量池中废奔的常量和不再使用的类型

    展开全文
  • jvm运行时数据区

    2017-03-13 17:58:45
    JVM运行时的数据区以下内容转载自JVM运行时的数据区.理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),...JVM运行时数据区分类1.程序计数

    JVM运行时的数据区

    以下内容转载自JVM运行时的数据区.


    理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机制,那么前面的问题就会迎刃而解。在这片文章中,我们将简单了解JVM中有哪些运行时数据区以及这些数据区的工作机制。


    JVM运行时数据区分类

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

    2.JVM栈 (Java Virtual Machine Stacks)

    3.堆内存 (Heap Memory)

    4.方法区 (Method Area)

    5.运行时常量池 (Run-time Constant Pool)

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

    如图所示:

    这里写图片描述

    按线程持有划分

    查看上面的图,可以得知以上六个数据区其实线程私有还是共享,可以分为如下两种。

    单个线程私有(Managed Per-Thread) 属于这一种的数据区包含 程序计数器, JVM栈还有本地方法栈。 每个线程都私有这三个数据区,这些数据区在其所属的线程创建时初始化,并随着所属线程结束被销毁。

    多个线程共享 属于这一种的数据区包含 堆内存,方法区和运行时常量池。这些数据区可以被每一个线程访问,他们随着JVM启动而初始化,同时伴随JVM关闭而销毁。


    程序计数器

    在通用的计算机体系中,程序计数器用来记录当前正在执行的指令,在JVM中也是如此。程序计数器是线程私有,所以当一个新的线程创建时,程序计数器也会创建。由于Java是支持多线程,Java中的程序计数器用来记录当前线程中正在执行的指令。如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined。注意这个区域是唯一一个不抛出OutOfMemoryError的运行时数据区。


    JVM栈

    在介绍JVM栈之前,简单介绍一个概念,栈帧

    栈帧

    一个栈帧随着一个方法的调用开始而创建,这个方法调用完成而销毁。栈帧内存放者方法中的局部变量,操作数栈等数据。

    JVM栈只对栈帧进行存储,压栈和出栈操作。栈内存的大小可以有两种设置,固定值和根据线程需要动态增长。在JVM栈这个数据区可能会发生抛出两种错误。

    StackOverflowError 出现在栈内存设置成固定值的时候,当程序执行需要的栈内存超过设定的固定值会抛出这个错误。
    OutOfMemoryError 出现在栈内存设置成动态增长的时候,当JVM尝试申请的内存大小超过了其可用内存时会抛出这个错误。


    堆数据区

    堆数据区是用来存放对象和数组(特殊的对象)。堆内存由多个线程共享。堆内存随着JVM启动而创建。众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。


    方法区

    在JVM规范中,方法区被视为堆内存的一个逻辑部分。这一点可能由于具体的JVM实现而不同,甚至在方法区不实现垃圾回收处理也是可以的。方法区和堆内存一样被多个线程访问,方法区中存放类的信息,比如类加载器引用,属性,方法代码和构造方法和常量等。当方法区的可用内存无法满足内存分配需求时,JVM会抛出OutOfMemoryError错误。


    运行时常量池

    运行时常量池创建在方法区,当一个类或者一个接口被创建的时候,JVM会创建一个运行时常量池。一个运行时常量池实际上是一个类或者接口的class文件中常量池表(constant_pool table)的运行时展示形式。一个运行时常量池包含了多种类型的常量,从诸如运行时可以确定的数值型字面量到运行时才能决定的方法和属性引用。当运行时常量池无法满足于内存分配需求时,JVM会抛出OutOfMemoryError错误。


    本地方法栈

    一个支持native方法调用的JVM实现,需要有这样一个数据区,就是本地方法栈,Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。一个不支持本地方法执行的JVM没有必要实现这个数据区域。本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误.


    参考:
    java中堆和栈的区别

    展开全文
  • 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些,然后分别介绍它们的特点,并指出给出一些HotSpot虚拟机实现的...1-2、Java内存区域与JVM运行时数据区 如上图, Java虚拟机规范...
  • JVM运行时数据区

    2016-06-28 10:09:17
    理解JVM运行时的数据区是Java编程中的进阶部分。我们在开发中都遇到过一个很...在这片文章中,我们将简单了解JVM中有哪些运行时数据区以及这些数据区的工作机制。 JVM运行时数据区分类 程序计数器 (Program Counte
  • 运行时数据区 背一下:堆、栈(虚拟机栈、本地方法栈)、程序计数器、方法区(包含常量池)。除此之外还有本地方法接口和方法库,让方法跑起来的执行引擎。 这些都是干嘛的,怎么运作的? 堆:存对象用的,我们new...
  • 转自:https://blog.csdn.net/tjiyu/article/details/53915869下面我们详细了解Java内存区域:先说明JVM...1、Java内存区域概述1-2、Java内存区域与JVM运行时数据区如上图, Java虚拟机规范定义了字节码执行期间使用...
  • 运行时数据区背一下:堆、栈(虚拟机栈、本地方法栈)、程序计数器、方法区(包含常量池)。除此之外还有本地方法接口和方法库,让方法跑起来的执行引擎。这些都是干嘛的,怎么运作的?堆:存对象用的,我们new出来的...
  • 我们先来看看运行时数据区包括哪些东西: 今天总结一下 运行时数据区的程序计数器(Program Counter Register): 每一个Java线程都一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非Native方法,...
  • 运行时数据区相关面试题JVM内存分区堆方法区 运行时数据区整体图: JVM内存分区 说一下JVM内存模型吧,有哪些区?分别干什么的?(百度三面) JVM内存分哪几个区,每个区的作用是什么?(蚂蚁金服) JVM内存分布/...
  • jvm-运行时数据区(二)

    2018-07-11 15:39:41
    1.什么是运行时数据区运行时数据区又包括哪几个部分,每个部分的功能是什么,在jdk版本迭代时,又对运行时数据区做了哪些改进。 2.jvm在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些...
  • 运行时数据区有哪些?一个运行时数据区包含多个线程,这些线程共享方法区和堆,每个线程包含了程序计数器、虚拟机栈和本地方法栈程序计数器(Program Counter Register)JVM会给每个线程一个独立的程序计数器,计数器...
  • Q1 : JVM内存模型,有哪些区,分别的作用? 类加载子系统将class文件加载到运行时数据区 class文件内容会按照规范加载到运行时数据区的不同区域 执行引擎通过运行时数据区进行指令执行 运行时数据区分类: ...
  • JVM(八)运行时数据区之方法区 方法区同堆一样,也是线程共享,并且具有垃圾回收动作的一块区域,用于存储已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据。 (上图根据jdk不同版本,...
  • 百度 三面:说一下JVM内存模型吧,有哪些区?分别干什么的? 蚂蚁金服: ...二面:讲讲jvm运行时数据库区 什么时候对象会进入老年代? 京东: JVM的内存结构,Eden和Survivor比例 。 JVM内存为什么要分成
  • 前一篇我们从整体上认识一下JVM哪些部分组成,现在我们开始着重了解JVM的核心部分-运行时数据区 Java虚拟机在运行程序的过程中会把它所管理的内存划分为若干个不同的数据区,基于内存是否能被线程所共享,内存可...
  • Android不管是5.0之前的DVM还是现在的ART,不管是java 开发的还是Kotlin开发的,其本质上都是运行在虚拟机中的,那么我们必要了解JVM的内存模型是什么样子的,哪些地方可能会产生OOM或者stackoverflo。 内存模型 ...
  • 1-运行时数据区内部结构概述 关于线程间共享的说明 2-线程 JVM系统线程 3-程序计数器(PC寄存器) 1.PC Register介绍 2.举例说明 3.两个常见问题 4.CPU时间片 4-虚拟机栈 1.虚拟机栈该概述 虚拟机栈出现...
  • 文章目录前言一、虚拟机栈的概述虚拟机栈出现的背景内存中的栈与堆虚拟机栈基本内容虚拟机栈的特点面试题:开发中遇见的异常有哪些?二、虚拟机栈的存储单位栈中存储什么呢?栈运行原理栈桢的内部结构三、栈桢的局部...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 251
精华内容 100
关键字:

jvm运行时数据区有哪些