java-五大内存图

Posted 杂货商

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-五大内存图相关的知识,希望对你有一定的参考价值。

 

 

jrm—Java虚拟机在进行程序运行时会向cpu申请一个内存约为10%左右,该内存被jrm分为5大区域

1、程序计数器

  程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器。

  那么计数器记录虚拟机字节码指令的地址。如果为native【底层方法】,那么计数器为空。

 

2、Java栈(虚拟机栈)

栈描述的是Java方法执行的内存模型。

每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

平时说的栈一般指局部变量表部分。

局部变量表所需要的内存空间在编译期完成分配,当进入一个方法时,这个方法在栈中需要分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表大小。

Java虚拟机栈可能出现两种类型的异常:

  1. 线程请求的栈深度大于虚拟机允许的栈深度,将抛出StackOverflowError。
  2. 虚拟机栈空间可以动态扩展,当动态扩展是无法申请到足够的空间时,抛出OutOfMemory异常

--动态链接:

符号引用与直接引用:
如:在Java中,存在两个类:A类、B类,A类存在对B类的方法调用,那么在编译期间,即静态时刻,A对B的方法调用,
它们这种地址关系实际上是不知道的。什么时候才能知道?两种情况:①在类加载的时候才可以知道这种关系,②只有当
真正开始调用的时候才能唯一确定目标调用的方法的地址是什么。由此引入了两个概念:符号引用与直接引用。 符号引用:   ①有些符号引用是在类加载阶段或是第一次使用时就会转换为直接引用,这种转换叫做静态解析;
  ②另外一些符号引用则是在每次运行期转换为直接引用,这种转换叫做动态链接,这体现为Java的多态性。

 

3、本地方法栈

本地方法栈是与虚拟机栈发挥的作用十分相似,区别是虚拟机栈执行的是Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务,可能底层调用的c或者c++,我们打开jdk安装目录可以看到也有很多用c编写的文件,可能就是native方法所调用的c代码。

 

4、堆

堆是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。

java虚拟机规范对这块的描述是:所有对象实例及数组都要在堆上分配内存,但随着JIT编译器的发展和逃逸分析技术的成熟,这个说法也不是那么绝对,但是大多数情况都是这样的。

即时编译器:可以把把Java的字节码,包括需要被解释的指令的程序)转换成可以直接发送给处理器的指令的程序)

逃逸分析:通过逃逸分析来决定某些实例或者变量是否要在堆中进行分配,如果开启了逃逸分析,即可将这些变量直接在栈上进行分配,而非堆上进行分配。这些变量的指针可以被全局所引用,或者其其它线程所引用。

堆是所有线程共享的,它的目的是存放对象实例。

 

5、方法区

方法区同堆一样,是所有线程共享的内存区域,为了区分堆,又被称为非堆。

方法区用于存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量加载类的时候就被加载到方法区中。

在老版jdk,方法区也被称为永久代。

不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。

 

以上是关于java-五大内存图的主要内容,如果未能解决你的问题,请参考以下文章

java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段

Oracle架构实现原理含五大进程解析

实例详解C++程序的五大内存分区

JVM系列之四:运行时数据区

一:jvm的五大内存区

iOS内存五大分区