zoukankan      html  css  js  c++  java
  • JVM学习笔记(一) ——Java虚拟机内存结构

    JAVA虚拟机内存结构

    • JAVA虚拟机内存结构可分为公有和私有两部分
      • 公有: 堆、方法区、运行时常量池
      • 私有: 程序计数器、JAVA虚拟机栈、本地方法栈

    JAVA虚拟机内存结构

    1.1 程序计数器

    • 可以看当前线程所执行字节码的行号指示器
      • 分支、循环、跳转、异常处理等基础功能都需要依赖计数器完成
      • Java虚拟机的多线程是通过线程轮流切换并分配执行时间的方式来实现的,因此任何一个时刻,一个处理器(多核处理器的一个内核)都只会执行一条线程中的指令。因此,通过程序计数器可以做到线程切换后能够恢复到正确的执行位置。
    • 如果线程正在执行的是一个Java方法,那么计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,计数器则为空。
    • 程序计数器是JVM中唯一个没有OOM的区域

    1.2 JAVA虚拟机栈

    • 线程私有的,生命周期与线程相同。
    • 虚拟机描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表操作数栈动态链接方法出口等。

      局部变量表中存放了编译期可知的各种基本数据类型、对象引用和returnAddress类型

    • 两种异常状况:
      • StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度
      • OutOfMemoryError: 如果可以扩展,但申请不到足够的内存

    1.3 本地方法栈

    • 与虚拟机栈十分相似、区别在于虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务
    • 两种异常状况:
      • StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度
      • OutOfMemoryError: 如果可以扩展,但申请不到足够的内存

    1.4 JAVA堆

    • Java Heap是虚拟机所管理的内存中最大的一块,是被所有线程所共享的一块内存区域。

    • 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配。Java堆可以处于不连续的空间中,只要逻辑上相连即可

      之所以说几乎是因为有特殊情况,有些时候小对象会直接在栈上进行分配,这种现象我们称之为「栈上分配」

    • Java堆是垃圾收集器管理的主要区域。从内存回收的角度,由于现在收集器基本都采用分代回收算法,所以Java队还可细分为:新生代老年代: 再细致一点的有:Eden空间From Survivor空间To Survivor等。
      Java Heap

    • 异常:

      • OutOfMemoryError:堆中内存没有能力完成实例分配

    1.5 方法区

    • 各个线程共享的内存区域。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
    • Java虚拟机规范对方法区的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾回收,相对而言,垃圾回收行为在方法区比较少见但并非数据进入了方法区就如永久代的名字一样“永久”存在了。这部分的垃圾回收主要针对常量池的回收和对类型的卸载。很多人更愿意把方法区称为“永久代”,但本质上两者并不等价,只是HotSpot虚拟机设计人员选择把GC分代收集扩展至方法区而已。
    • 异常:
      • OutOfMemoryError:方法区无法满足内存分配需求

    1.6 运行时常量池

    • 方法区的一部分,方法区中除了存放有类的相关信息,如成员、方法或者接口等,还有各种字面量和符号引用,这部分数据就存放在运行时常量池
    • 异常
      • OutOfMemoryError:常量池无法满足内存分配需求

    1.7 直接内存

    • 并不是虚拟机运行时数据区的一部分,也是不虚拟机规范中定义的内存区域,但这部分也被频繁使用,也可能会导致OutOfMemoryError异常出现。
    • 在JDK1.4中新加入了NIO类,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

      通信数据传输可以通过NIO实现的,NIO使用的就是直接内存——更为直观的说,就是JVM外的本地内存。

    • 直接内存不受Java堆大小的限制,但是既然是内存,那么必然受系统内存的限制,除了JVM分配后的内存,以及其他进程使用的内存,剩下才能给直接内存使用。
    • 异常:
      • OutOfMemoryError:直接内存无法申请到足够空间









    推荐文章:

    https://www.cnblogs.com/yuhuiqing/p/12066733.html

    参考

    [1]周志明.深入理解Java虚拟机.北京:机械工业出版社
    [2]https://blog.csdn.net/o983950935/article/details/85849606
    [3]https://www.cnblogs.com/chanshuyi/p/jvm_serial_06_jvm_memory_model.html

  • 相关阅读:
    wpf 计算公式
    c#读取文件
    wpf布局控件总结
    一个接口多次使用的值得引起思考的小片段
    wpf之渐变色LinearGradientBrush
    路由
    HtmlHelper2
    HtmlHelper1
    ssh连接Ubuntu之access denied
    百万级数据库优化方案
  • 原文地址:https://www.cnblogs.com/ccink/p/13362043.html
Copyright © 2011-2022 走看看