欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识
原文出处: melonstreet

jvm的内存区域是怎么分另外">JVM的内存区域是怎么分另外?

JVM的内存分别中,有部门区域是线程私有的,有部门是属于整个JVM历程;有些区域会抛出OOM异常,有些则不会,相识JVM的内存区域分别以及特征,是定位线上内存问题的基本。那么JVM内存区域是怎么分另外呢?

首先是措施计数器(Program Counter Register),在JVM类型中,每个线程都有本身的措施计数器。这是一块较量小的内存空间,昆山软件开发,存储当前线程正在执行的Java要领的JVM指令地点,即字节码的行号。假如正在执行Native要领,则这个计数器为空。该内存区域是独一一个在Java虚拟机类型中没有划定任何OOM环境的内存区域。

第二,Java虚拟机栈(Java Virtal Machine Stack),同样也是属于线程私有区域,每个线程在建设的时候城市建设一个虚拟机栈,生命周期与线程一致,线程退出时,线程的虚拟机栈也接纳。虚拟机栈内部保持一个个的栈帧,每次要领挪用城市举办压栈,JVM对栈帧的操纵只有出栈和压栈两种,要领挪用竣事时会举办出栈操纵。

该区域存储着局部变量表,编译时期可知的各类根基范例数据、工具引用、要领出口等信息。

第三,当处所法栈(Native Method Stack)与虚拟机栈雷同,当处所法栈是在挪用当处所法时利用的栈,每个线程都有一个当处所法栈。

第四,堆(Heap),险些所有建设的Java工具实例,都是被直接分派到堆上的。堆被所有的线程所共享,在堆上的区域,会被垃圾接纳器做进一步分别,譬喻新生代、暮年月的分别。Java虚拟机在启动的时候,可以利用“Xmx”之类的参数指定堆区域的巨细。

第五,要领区(Method Area)。要领区与堆一样,也是所有的线程所共享,存储被虚拟机加载的元(Meta)数据,包罗类信息、常量、静态变量、即时编译器编译后的代码等数据。这里需要留意的是运行时常量池也在要领区中。按照Java虚拟机类型的划定,当要领区无法满意内存分派需求时,将抛出OutOfMemoryError异常。由于早期HotSpot JVM的实现,将CG分代收集拓展到了要领区,因此许多人会将要领区称为永久代。Oracle JDK8中已永久代移除永久代,同时增加了元数据区(Metaspace)。

第六,运行时常量池(Run-Time Constant Pool),这是要领区的一部门,受到要领区内存的限制,当常量池无法再申请到内存时,会抛出OutOfMemoryError异常。
在Class文件中,除了有类的版本、要领、字段、接口等描写信息外,尚有一项信息是常量池。每个Class文件的头四个字节称为Magic Number,它的浸染是确定这是否是一个可以被虚拟机接管的文件;接着的四个字节存储的是Class文件的版本号。紧挨着版本号之后的,就是常量池进口了。常量池主要存放两大类常量:

  • 字面量(Literal),如文本字符串、final常量值
  • 标记引用,存放了与编译相关的一些常量,因为Java不像C++那样有毗连的进程,因此字段要领这些标记引用在运行期就需要举办转换,以便获得真正的内存进口地点。
    class文件中的常量池,也称为静态常量池,JVM虚拟机完成类装载操纵后,会把静态常量池加载到内存中,存放在运行时常量池。
  • 第七,直接内存(Direct Memory),直接内存并不属于Java类型划定的属于Java虚拟机运行时数据区的一部门。Java的NIO可以利用Native要领直接在java堆外分派内存,利用DirectByteBuffer工具作为这个堆外内存的引用。

    下面这张图,反应了运行中的Java历程内存占用环境:

    关于 JVM 内存 <a href=劳务调派系统的 N 个问题" src="http://www.importnew.com/https:/images2018.cnblogs.com/blog/610439/201809/610439-20180912202934115-229637682.png" />

    OOM大概产生在哪些区域上?

    按照javadoc的描写,OOM是指JVM的内存不足用了,同时垃圾收集器也无法提供更多的内存。从描写中可以看出,在JVM抛出OutOfMemoryError之前,垃圾收集器一般会出马先实验接纳内存。
    从上面阐明的Java数据区来看,除了措施计数器不会产生OOM外,哪些区域会产生OOM的环境呢?

    第一,堆内存。堆内存不敷是最常见的发送OOM的原因之一,假如在堆中没有内存完成工具实例的分派,而且堆无法再扩展时,将抛出OutOfMemoryError异常,抛出的错误信息是“java.lang.OutOfMemoryError:Java heap space”。当前主流的JVM可以通过-Xmx和-Xms来节制堆内存的巨细,产生堆上OOM的大概是存在内存泄露,也大概是堆巨细分派不公道。

    第二,Java虚拟机栈和当处所法栈,这两个区域的区别不外是虚拟机栈为虚拟机执行Java要领处事,而当处所法栈则为虚拟机利用到的Native要领处事,在内存分派异常上是沟通的。在JVM类型中,对Java虚拟机栈划定了两种异常:1.假如线程请求的栈大于所分派的栈巨细,则抛出StackOverFlowError错误,好比举办了一个不会遏制的递归挪用;2. 假如虚拟机栈是可以动态拓展的,拓展时无法申请到足够的内存,则抛出OutOfMemoryError错误。