美文网首页
Java内存分配与内存溢出

Java内存分配与内存溢出

作者: T_log | 来源:发表于2018-07-06 16:08 被阅读3次

java 与C++之间有一堵内存分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人想出来。


企业微信截图_259be09e-cb21-476d-b351-2c2c8144bc3e.png

运行时数据区域

  1. 程序计数器 (Program Counter Register)是一块较小的内存区域,可以看成当前线程所执行的字节码的行号指示器。属于线程私有的内存区域。在虚拟机概念模型中,字节码解释器就是通过这个行号指示器的值,来选取下一条需要执行的字节码指令。
    由于Java虚拟机的多线程是通过线程轮流切换并分配处理器时间的方式实现的,所以在任何一个确定的时刻,一个cpu只会处理一条线程中的指令。那当恢复其他线程的运行时,就是通过这个程序计数器来恢复到上一次执行到的
    位置,因此,程序计数器是线程私有的,每个线程都对应着一个独立的程序计数器。
    在JVM执行Java程序时,程序计数器记录的是虚拟机字节码指令的地址。
  2. Java虚拟机栈(java Virtual Machine Stacks),和程序计数器一样,也属于线程私有的内存区域。生命周期和线程相同。虚拟机栈描述的是方法执行的内存模型;每个方法在执行的同时,会创建一个栈帧(Stacj Frame),用于存储
    局部变量表、操作数栈、动态链接、方法出口灯信息,每个方法从调用开始,到执行完成,都会伴随着一个栈帧在虚拟机栈中的入栈和出栈的执行过程。
    局部变量表: 存放了编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double)、对象引用类型referenct,局部变量表所需的内存空间在编译期间就已经完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的。方法运行期间不会改变布局变量表的大小。
    在Java虚拟机规范中,对Java虚拟机栈规定了两种异常情况
    如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常
    如果虚拟机栈可以动态扩展,如果扩展时,无法申请到足够的内存,将会抛出OutOfMemoryError异常
  1. 本地方法栈(Native Method Stack)与虚拟机所发挥的作用相似。区别在于,虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈为虚拟机使用到的Native方法服务
  2. Java堆(Heap)是Java虚拟机管理的内存中最大的一块,Java堆是被所有线程共享的一块内存区域。随虚拟机的启动而创建,Java堆唯一的目的就是存放对象实例。几乎所有的对象实例都存放在Java堆中。在Java虚拟机规范中的描述是:
    所有的对象实例和数组都要在堆上分配内存。但是随着(JIT JUST IN TIME)的发展和逃逸分析技术的逐渐成熟,栈上分配,标量替换优化技术将会导致一些微妙的变化,所有的对象都分配在Java堆上,也并不是那么的绝对了。
    Java堆也是GC回收垃圾的主要内存区域。基于收集器的分代收集算法,Java堆可以分为新生代和老年代,新生代还可以分为:Eden空间、From Survior空间、To Survior空间,其实还有更细的划分方式,不管如何划分,都是为了更好的回收内存空间而已
    5.方法区(Method Area)与Java堆一样,都是线程共享的内存区域。主要用来存储被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
    6.运行时常量池(Runtime Constant Pool),其实是方法区的一部分。Class文件中除了有类的版本信息、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容将会在类加载后进入方法区的运行时常量池中存放。运行时常量池除了保存Class文件中描述的符号引用外,还会把翻译出来的直接引用也存储在运行时常量池中。

符号引用 :符号引用以一组符号来描述所引用的目标。符号引用可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可,符号引用和虚拟机的布局无关。个人理解为:在编译的时候一个每个java类都会被编译成一个class文件,但在编译的时候虚拟机并不知道所引用类的地址,多以就用符号引用来代替,而在这个解析阶段就是为了把这个符号引用转化成为真正的地址的阶段。
直接引用可以是:
1:直接指向目标的指针。(个人理解为:指向对象,类变量和类方法的指针)
2:相对偏移量。 (指向实例的变量,方法的指针)
3:一个间接定位到对象的句柄。

  1. 直接内存(Direct Memory)并非Java虚拟机规范中定义的内存区域

参考
周志明 《深入理解Java虚拟机》
https://blog.csdn.net/qq_34402394/article/details/72793119
https://blog.csdn.net/qq_22884121/article/details/52700806

相关文章

  • JVM 常见内容汇总

    面试题 对象 对象的创建 分配内存 对象头 内存溢出 内存溢出与内存泄漏 内存溢出:系统无法再分配内存空间。 内存...

  • Java内存分配与内存溢出

    java 与C++之间有一堵内存分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人想出来。企业微信截...

  • JVM学习二(Java内存区域与内存溢出异常)

    Java内存区域与内存溢出异常 (一)HotSpot虚拟机对象探秘 1、对象的创建 (1)为对象分配内存 http...

  • JVM-java内存区域与内存溢出异常

    JVM-java内存区域与内存溢出异常 1 说明 java 与 c++之间有一堵由内存动态分配和垃圾回收技术所围成...

  • JVM之内存模型

    Java内存内存区域图 内存泄露和内存溢出的区别 内存泄露是指分配出去的内存没有被回收回来 内存溢出是指程序所需要...

  • 深入理解java虚拟机总览

    一.自动内存管理机制 1.java内存区域与内存溢出异常 2.垃圾收集器与内存分配策略 3.虚拟机性能监控与故障处...

  • JVM阅读笔记-初学

    深入理解JVM 第一章 走近JAVA 第二章 Java内存区域与内存溢出异常 第三章 垃圾收集器与内存分配策略 第...

  • JAVA内存区域与内存溢出异常

    JAVA内存区域与内存溢出异常 一 Java内存区域 Java虚拟机在执行java程序的...

  • JVM学习(1) 自动内存管理机制

    Java内存区域与内存溢出异常 Java和C++之间有一堵由内存动态分配和垃圾手机技术所围成的高墙,墙外面的人想进...

  • 《深入理解Java虚拟机》总纲

    第2章 Java内存区域与内存溢出异常 第3章 垃圾收集器与内存分配策略 第4章 虚拟机性能监控与故障处理工具 第...

网友评论

      本文标题:Java内存分配与内存溢出

      本文链接:https://www.haomeiwen.com/subject/apdpuftx.html