快捷搜索:    1747    as  haobc

JVM从入门到精通系列(二):JVM内存区域及运行时内存

JVM内存区域 JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA ...
 

JVM存储器区域

JVM存储器区域主要分为螺纹专用区域[程序计数器,虚拟机堆,本地方法面积],线程共享区域[Java堆,方法区域],和直接存储器。

线程的专用数据区的生命周期是相同的,一个线程的,并且它被创建/毁根据用户线程(在热点VM的开始/结束,每个线程被直接映射到本地线程的操作系统,所以存储器区域对应这部分的存储/死神来了本地线程的生命/死亡)。

在创建线程共享区域/销毁虚拟机启动/关机。

直接存储器不是JVM运行时数据区的一部分,但它也将是经常使用的:氧化镍在JDK 1.4引入提供了一种基于信道并缓冲IO模式。它可以使用本地函数库来直接分配的堆内存出来,然后使用对象为引用该内存的操作(请参阅Java I / O扩展的详细信息),从而避免使用Java堆和本机E-堆拷贝数据来回走动,所以性能在某些情况下可以显著改善。

1.程序计数器(线程私有)

小的存储器空间是由当前线程执行字节码的行数指示器。每个线程必须有一个独立的程序计数器,也称为“线程私人”内存。

如果Java方法正在执行时,计数器记录的虚拟机(当前指令的地址)的字节代码指令的地址。如果它仍然是一个本地方法,它是空的。

该存储区域是在虚拟机中没有指定的OutOfMemoryError条件的唯一区域。

2.虚拟机堆(线程私有)

是描述Java方法的执行的存储器模型。每个方法将创建一个栈帧来存储局部变量表,操作数栈,动态链接,方法退出和其它信息,同时执行。从堆栈帧调用每个方法对应于该方法的执行过程中堆叠在虚拟机的堆栈帧。

帧是用于存储数据和部分处理结果的数据结构,并且还用于处理动态链接,方法返回值和调度异常。栈帧与方法调用创建并与该方法的结束时被销毁 - 该方法是否正常或异常完成(抛未在方法中捕获的异常)被认为是该方法的结束。

3.局部方法区域(线程私有)

本地方法区域具有相同的功能的Java堆。不同的是,虚拟机栈执行Java方法服务,而本地方法栈执行本地方法的服务。如果虚拟机实现使用C-联动的模式,以支持本地调用,那么堆栈将是C组,但HotSpot虚拟机直接结合本地方法堆栈和虚拟机堆栈之一。

4.堆线程共享的运行时数据区

是由线程共享的存储器区域。创建的对象和数组存储在Java堆内存,这也是垃圾收集垃圾收集的最重要的内存区域。由于现代VMS采用代收集算法,Java堆也可以细分为:新一代(伊甸园区,从幸存者区和遗属区)和老一代从GC的角度。

5.方法区域/永久代(线程共享)

是通常被称为永久代,其被用于存储类别信息,常量,静态变量,实时编译器编译的代码和由加载其它数据JVM。 HotSpot虚拟机扩展GC代收集到方法区域,那就是用Java堆的永久代实现方法区,使热点的垃圾收集器可以像管理Java堆是一样的管理这部分内存,而不是开发方法区特殊的内存管理器(永久内存回收的主要目的是回收常量池和卸载的类型,所以收入普遍较小)。

运行时间常数池是方法区域的一部分。除了类版本,字段,方法,接口和其它描述,也有在类文件中,其用于存储在编译过程中产生的各种文字和符号引用一个常量池表。类被装载之后的这部分内容将被存储在方法区域的运行时常量池。 Java虚拟机对类文件的各个部分(包括自然常量池)的格式严格的规定。每个字节用于存储数据必须符合说明书的要求,所以,它可以被识别,加载并通过虚拟机执行。的

JVM运行时存储器

Java堆也可以从GC的透视到新一代细分(伊甸区域,从幸存者面积和幸存者区域)和老一代

1.新生代

用于存储新对象。通常,它占据了堆空​​间的三分之一。由于频繁创建对象的,minorgc经常在新一代触发垃圾收集。新生代可划分为三个区域:伊甸区,servivorfrom区和servivorto区。

1.1。伊甸区

新的Java的发源地对象(如果新创建的对象占用了大量的内存,它们直接分配到年老)。当伊甸园区域的内存不够,minorgc将被触发回收新一代区。

1.2。 Servivorfrom

最后GC的幸存者,因为这GC的扫描人。

1.3。 Servivorto

保留了minorgc幸存者。

1.4。 >明确 - >交换)

Minorgc使用复制算法。

1:伊甸,servicorfrom到servicorto,年龄+ 1

首先,在伊甸幸存对象和servivorfrom复制到servicorfrom(如果有一个对象的年龄并满足老化的标准,将其分配给老化面积) ,并在同一时间,添加这些对象+ 1岁(如果servicorfrom是不够的,把他们在老化区域);

2:清晰伊甸,servicorfrom

,然后清除伊甸和servicorfrom的对象;

3:servicorfrom和servicorfrom互换

。最后,servicorfrom和servicorfrom互换。原来servicorfrom成为下一个GC的servicorfrom区域。

2.在过去

主要存储长期记忆对象的应用程序。

旧对象,更稳定,所以majorgc不会频繁执行。主要GC之前,minorgc通常首先进行,以便有新世代进入老年对象,造成空间不足触发之前。当连续空间没有找到足够的可分配给新创建的大对象,majorgc将提前触发垃圾回收以腾出空间。

majorgc使用该商标清算算法:首先,扫描所有老一代的一次,标志着生命物体,然后回收无人盯防的对象。 Majorgc需要很长的时间,因为它需要进行扫描和回收。主要GC会产生内存碎片。为了减少记忆力减退,我们通常需要合并或者将其标记为接下来的直接分配。当老年太满,以适应,一个内存溢出异常将被抛出。

3.常驻代

指的存储器中的永久存储区域。它主要存储类和元(元数据)的信息。在加载时类放入永久区域。它是从哪里实例存储的区域不同。在主程序运行期间GC不会清除永久区域。因此,这也导致永久代区域与加载的类的增加,最后一个OOM抛出异常膨胀。

3.1。 Java8和元数据

在java8,永久代已被取出,并通过称为“元数据区域”(甲基空间)的区域所取代。的元空间的本质是相似的永久代。元的空间和持久代的最大区别是,元空间中的虚拟机不存在的,但使用本地内存。因此,默认情况下,元空间的大小只受本地内存的限制。类的元数据被放入本机内存,串池和类静态变量放入Java堆,让多少类的元数据可以被加载由MaxPermSize参数不再受控制,而是由系统的实际可用空间。

觉得文章是好的给小弟一点点的关注!加入我的个人粉丝团(Java体系结构技术堆栈:644872653),以获得一个Java面试的书“Java核心知识点排列PDF ”和“Java的208面试题(含答案)”!

您可能还会对下面的文章感兴趣: