栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

JVM第一阶段学习总结分享

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM第一阶段学习总结分享

运行时数据区  程序计数器(Program Counter Register)

    在深入理解java虚拟机种是这样定义的:程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里[1],字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

    程序计数器为线程私有的,生命周期和线程相同

    通过javap 反编译可以看到 0 1 2 3 4的序号,在运行时jvm将会创建计数器按照这个序号创建相关的空间存入相关字节码指令

 public static void main(java.lang.String[]);

    descriptor: ([Ljava/lang/String;)V

    flags: (0x0009) ACC_PUBLIC, ACC_STATIC

    Code:

      stack=2, locals=7, args_size=1

         0: iconst_1

         1: istore_1

         2: iconst_2

         3: istore_2

         4: iload_1

         5: iload_2

         6: iadd

         7: istore_3

         8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;

        11: iload_3

        12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V

        15: ldc           #4                  // String 1

        17: astore        4

        19: ldc           #5                  // String 2

        21: astore        5

        23: aload         4

        25: aload         5

        27: invokedynamic #6,  0              // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

        32: astore        6

        34: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;

        37: aload         6

        39: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V

        42: return

 

栈(Java Virtual Machine Stack)

    在深入理解java虚拟机种的定义为:与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧[1](Stack frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

    如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

    在debug时会发现方法被一个一个压入栈 当一个栈调用结束会进行出栈,如果有返回值将返回值返回给下一个栈帧在下一个栈帧运行代码,进行出栈操作

### 本地方法栈 (Native Method Stacks)

    在深入理解java虚拟机中定义为:本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

    JVM调用非java语言的方法时所用到的栈。

    与虚拟机栈一样,本地方法栈也会在栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常。

 堆 (Java Heap)

    在深入理解java虚拟机中定义为:对于Java应用程序来说,Java堆(Java Heap)是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。在《Java虚拟机规范》中对Java堆的描述是:“所有的对象实例以及数组都应当在堆上分配[1]”,而这里笔者写的“几乎”是指从实现角度来看,随着Java语言的发展,现在已经能看到些许迹象表明日后可能出现值类型的支持,即使只考虑现在,由于即时编译技术的进步,尤其是逃逸分析技术的日渐强大,栈上分配、标量替换[2]优化手段已经导致一些微妙的变化悄然发生,所以说Java对象实例都分配在堆上也渐渐变得不是那么绝对了。

    java堆中经常出现 “新生代” “老年代” “永久代” “Eden空间” “From Survivor空间” “To Survivor空间”等名词。

    java堆因为是线程共享的所以要警惕线程安全问题,

    如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

方法区(Method Area)

    在深入理解java虚拟机中定义为:方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。虽然《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫作“非堆”(Non-Heap),目的是与Java堆区分开来。

    1.8之前方法区在永久代上,1.8之后方法区在非堆Non-Heap(元空间)中。

    如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池

     在深入理解java虚拟机中定义为:运行时常量池(Runtime Constant Pool)是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

    当常量池无法再申请到内存时会抛出OutOfMemoryError异常。

 直接内存(Direct Memory)

     在深入理解java虚拟机中定义为:直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。在JDK 1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。被分配的堆外内存就称为直接内存

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/308440.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号