Java教程

Java 8 的内存结构

本文主要是介绍Java 8 的内存结构,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

 

 

虚拟机内存与本地内存的区别

Java虚拟机在执行的时候会把管理的内存分配成不同的区域,这些区域被称为虚拟机内存,同时,对于虚拟机没有直接管理的物理内存,也有一定的利用,这些被利用却不在虚拟机内存数据区的内存,我们称它为本地内存,这两种内存有一定的区别:

JVM内存

  • 受虚拟机内存大小的参数控制,当大小超过参数设置的大小时就会报OOM

本地内存

  • 本地内存不受虚拟机内存参数的限制,只受物理内存容量的限制
  • 虽然不受参数的限制,但是如果内存的占用超出物理内存的大小,同样也会报OOM

 

(1)程序计数器(Program Counter Register)

程序计数器就是当前线程所执行的字节码的行号指示器,通过改变计数器的值,来选取下一行指令,通过他来实现跳转、循环、恢复线程等功能

  • 在任何时刻,一个处理器内核只能运行一个线程,多线程是通过线程轮流切换,分配时间来完成的,这就需要有一个标志来记住每个线程执行到了哪里,这里便需要到了程序计数器。
  • 所以,程序计数器是线程私有的,每个线程都已自己的程序计数器。

(2)虚拟机栈(JVM Stacks)

 

 

 虚拟机栈是线程私有的,随线程生灭。

每个方法被执行的时候,都会在虚拟机栈中同步创建一个栈帧(stack frame)。

每个栈帧的包含如下的内容

  • 局部变量表

    • 局部变量表中存储着方法里的java基本数据类型(byte/boolean/char/int/long/double/float/short)以及对象的引用(注:这里的基本数据类型指的是方法内的局部变量)
  • 操作数栈

  • 动态连接

  • 方法返回地址

方法被执行时入栈,执行完后出栈。

虚拟机栈可能会抛出两种异常:

  • 如果线程请求的栈深度大于虚拟机所规定的栈深度,则会抛出StackOverFlowError即栈溢出
  • 如果虚拟机的栈容量可以动态扩展,那么当虚拟机栈申请不到内存时会抛出OutOfMemoryError即OOM内存溢出

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

本地方法栈与虚拟机栈的作用是相似的,都会抛出OutOfMemoryError和StackOverFlowError,都是线程私有的,主要的区别在于:

  • 虚拟机栈执行的是java方法
  • 本地方法栈执行的是native方法

(4)Java堆(Java Heap)

Java堆(Java Heap)

java堆是JVM内存中最大的一块,由所有线程共享,是由垃圾收集器管理的内存区域,主要存放对象实例,当然由于java虚拟机的发展,堆中也多了许多东西,现在主要有:

  • 对象实例

    • 类初始化生成的对象
    • 基本数据类型的数组也是对象实例
  • 字符串常量池

    • 字符串常量池原本存放于方法区,jdk7开始放置于堆中。
    • 字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table
  • 静态变量

    • 静态变量是有static修饰的变量,jdk7时从方法区迁移至堆中
  • 线程分配缓冲区(Thread Local Allocation Buffer)

    • 线程私有,但是不影响java堆的共性
    • 增加线程分配缓冲区是为了提升对象分配时的效率

java堆既可以是固定大小的,也可以是可扩展的(通过参数-Xmx和-Xms设定),如果堆无法扩展或者无法分配内存时也会报OOM。

(5)方法区(Method Area)

类元信息(Klass)

  • 类元信息在类编译期间放入方法区,里面放置了类的基本信息,包括类的版本、字段、方法、接口以及常量池表(Constant Pool Table)

运行时常量池(Runtime Constant Pool)

  • 运行时常量池主要存放在类加载后被解析的字面量与符号引用,但不止这些
  • 运行时常量池具备动态性,可以添加数据,比较多的使用就是String类的intern()方法

直接内存

直接内存位于本地内存,不属于JVM内存,但是也会在物理内存耗尽的时候报OOM。

 

 

Native方法

由于java是一门高级语言,离硬件底层比较远,有时候无法操作底层的资源,于是,java添加了native关键字,被native关键字修饰的方法可以用其他语言重写,这样,我们就可以写一个本地方法,然后用C语言重写,这样来操作底层资源。当然,使用了native方法会导致系统的可移植性不高,这是需要注意的。

这篇关于Java 8 的内存结构的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!