Java教程

深入了解Java虚拟机

本文主要是介绍深入了解Java虚拟机,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

**今日计划 Java内存区域与内存溢出异常
概述
Java虚拟机具有自动内存管理机制

前言

提示:
1、Java虚拟机具有自动内存管理机制
2、Java虚拟机在执行java程序时,会把它管理的内存区域划分为不同的内存区域,各个区域具有不同的功能
3、Java运行时数据区有 程序计数器、虚拟机栈、本地方法栈、方法区、运行时常量池、直接内存


一、程序计数器是什么?

  1. i程序计数器是一块较小的内存区域,线程私有,可以看作是当前线程正在执行的字节码的行号指示器
  2. 字节码解释器就是改变这个程序计数器的值来选取下一条需要执行的字节码指令
  3. 每一条线程都有一个独立的程序计数器。为了切换线程后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器
  4. 程序计数器内存区域是唯一一个在Java虚拟机规范中规定没有任何OutOfMemoryError(内存溢出)情况的区域

二、Java虚拟机栈

  1. Java虚拟机栈描述的是Java方法执行的线程内存模型,是线程私有的
  2. Java虚拟机栈的生命周期与线程的生命周期相同
  3. Java虚拟机栈由多个栈帧组成
  4. 每一个方法的调用到执行都对应着栈中一个栈帧的入栈和出栈过程
  5. 栈帧用于存储局部变量表、操作数栈、动态连接、方法返回地址等信息
  6. 局部变量表存放了编译期可知的各种基本数据类型(byte、long、int、short、char、float、double、boolean)对象引用(reference类型不是对象本身,是一个指向对象起始地址的引用指针、也可能是指向一个代表对象的句柄或与此对象相关的位置)
  7. Java虚拟机栈内存在Java虚拟机规范中规定了两类异常状况
    1.如果线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError(栈溢出)异常
    2.虚拟机容量动态扩展时(HopStop虚拟机默认不支持动态扩展)当扩展时无法申请到足够的内存会抛出OutOfMemoryError(内存溢出)异常

三、本地方法栈

1、本地方法栈作用与虚拟机栈作用相似,线程私有
本地方法栈与虚拟栈的区别
a、本地方法栈为虚拟机使用到的本地方法服务
b、虚拟机栈为Java方法服务
2、、HotStop虚拟机把虚拟机栈与本地方法栈和二为一
3、本地方法栈在栈深度溢出抛出StackOverflowError(栈溢出)异常
本地方法栈在栈扩展失败(扩展时无法申请到足够的内存)抛出OutOfMemoryErro(内存溢出)异常

四、Java堆

1、Java堆是虚拟机所管理的最大的一块内存区,线程共享区域
2、Java堆在虚拟机创建时启动
3、.Java堆目的
1)存放对象实例,几乎所有的对象实例都在这里分配内存
4、Java堆也是垃圾收集器管理的区域
1)、主流的HopStop内部垃圾收集器基于经典分代设计
1.有新生代、老年代
2)新生代由一个Eden区 两个Survivor区组成
5、Java堆细分是为了更好的进行垃圾回收或更快的分配内存
6、Java虚拟机规范规定Java堆可以处于物理上不连续的内存空间中,但在逻辑上必须是连续的
7、Java堆可以是固定大小的,也是可扩展的
1)通过参数-Xmx() -Xms()设定
8、Java堆没有完成实例分配,堆无法扩展时,Java虚拟机抛出OutOfMemory异常

五、方法区

1、方法区用于存储已被虚拟机加载的类型信息、常量、静态常量、即时编译器编译后的代码缓存等数据,是线程共享区域
2、Java虚拟机规范是把方法区描述为堆的一个逻辑部分 但目前是与堆分开的
3、JDK8以前永久代实现虚拟机的方法区
4、JDK8用本地内存中实现的元数据代替永久代
5、Java虚拟机规范对方法区的约束不严格,可以像堆一样不需要连续的内存和可以选择固定大小或可扩展,还可以选择不实现垃圾回收
6、方法区的垃圾回收主要针对常量池的回收和对类型的卸载
7、Java虚拟机规范规定,如果方法区不满足新的内存分配需求时,抛出OutOfMemory(内存溢出)异常

六、运行时常量池

1、运行时常量池是方法区的一部分
2、运行时常量池用于存放编译期生成的各种字面量与符号引用,这部分在类加载后存放到方法区的运行时常量池中
3、符号引用翻译出来的直接引用也存储在运行时常量池中
4、运行时常量池特征 动态性
1)Java语言并不要求常量一定在编译期产生,运行期也可以将常量放入常量池中
2)String类的intern 方法
5、常量无法再申请到内存时会抛出OutOfMemory(内存溢出)异常

七、直接内存

1、直接内存并不是虚拟机运行时数据区的一部分,也不是Java虚拟定义的内存区域

这篇关于深入了解Java虚拟机的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!