多线程-JVM程序运行原理(1)

Java与JVM(Java Virtual Machine 简称:Java虚拟机)

Java与JVM

JVM运行时数据区

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

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

方法区

作用:存储加载类信息,常量,变量,JIT编译后的代码等数据.

GC:

  • 方法区的垃圾回收,但回收效率低
  • 回收主要针对常量池,和类型的卸载
  • 当方法去无法满足内存的时候,报OOM.

堆内存

作用:存在对象实例,几乎所有的对象,数组都在这里存放

  • 对于大多数应用来说,堆是JVM管理的内存中最大的一块内存区域,也是最容易OOM的区域
  • 大多数JVM都将堆实现为大小可扩展的,(通过-Xmx、-Xms控制)

live or die

引用计数器算法,存在两个对象相互引用的问题 .

可达性分析算法:

      主流的商用程序语言(Java、C#)都是通过可达性分析算法来判定对象是否 存活的,GC Roots可以是: 

  1. 虚拟机栈。
  2. 方法中静态属性引用的对象。 
  3. 方法区中常量引用的对象。
  4. Native方法引用的对象。

虚拟机栈

虚拟机栈:

      线程中方法执行的模型,每个方法执行时,就会在虚拟机栈中创建一个栈帧, 每个方法从调用到执行的过程,就对应着栈帧在虚拟机栈中从入栈到出栈的过程。

    栈帧:虚拟机栈由多个栈帧(Stack Fframe)组成。一个线程会执行一个或多个方法, 一个方法对应一个栈帧。

本地方法栈

本地方法栈:

  •  和虚拟机栈功能类似,虚拟机栈是为虚拟机执行JAVA方法而准备的, 本地方法栈是为虚拟机使用Native本地方法而准的。 
  • 《Java虚拟机规范》中对Native方法使用的语言、使用方式与数据结构没有强制规定。
  •  HotSpot虚拟机中虚拟机栈和本地方法栈合二为一。

程序计数器

程序计数器(Program Counter Register)记录当前线程执行字节码的位置,字节码解释器 工作时,就是通过改变计数器的值来选取下一条需要执行的字节码指令。 

  • 如果执行java方法,存储的是字节码指令地址,如果执行Native方法,则计数器值为空。 
  • 程序计数器是唯一一个在《JVM规范》中没有任何OOM的区域

直接内存 (不属于JVM内存区的)

直接内存不是JVM运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域, 是我们常说的堆外内存。

  • JDK1.4 引入NIO,它可以使用Native函数库直接分配堆外内存,然后通过一个存在在Java堆 中的DirectByteBuffer对象作为操作这块内存区域的引用进行操作。
  • 直接内存不受Java堆大小限制,当内存总和大于机器物理内存时,会OOM。
发布了121 篇原创文章 · 获赞 60 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/sdmxdzb/article/details/90482225