JVM简介与Java内存划分

JVM:java虚拟机

虚拟机:通过软件模拟的具有完整硬件功能,运行在完全隔离环境中的计算机系统。VMWare/Virtual Bos

JVM是通过软件模拟Java字节码指令集,JVM只保留了PC寄存器,而普遍的虚拟机有很多寄存器

从JDK1.3至今,HotSpot为默认JVM(垃圾回收机制和内存模型不同的虚拟机都不一样,下面讲的是HotSpot)

JVM不只能跑Java一门语言,如:Scala,Koltin

 

单核CPU:每一个具体时刻只有一个线程强占处理器资源

Java对内存的划分——>判断对象是否存活——>垃圾回收算法——>垃圾回收器(对垃圾回收算法的实现)——>JVM性能监测

 

问题:6块区域是哪6块,每块都干了那些事情,会产生那些异常

1、Java对内存的划分(基于HotSpot来说的)(按线程划分)——共6块

      1.1、线程私有内存:每个线程都有,并且彼此之间完全隔离

                      1、程序计数器

                                 1.1、程序计数器是比较小的内存空间,当前线程所执行的字节码的行号指示器

                                  1.2、记录内容

                                                  若当前线程执行的是Java方法,计数器记录的是正在执行的JVM字节码指令地址;

                                                  若当前线程执行的是native方法,计数器值为空

                                  1.3、程序计数器是唯一一块不会产生OOM(OutOfMemoryError)异常的区域

                        2、虚拟机栈——Java方法执行的内存模型

                                    2.1、虚拟机栈描述Java方法执行的内存模型

                                     2.2、每个方法执行的同时都会创建一个栈帧存储局部变量表、操作数栈、方法出口等信息。每个方法从调用到执行完毕的过程,对应一个栈帧在虚拟机栈的入栈与出栈过程

                                     2.3、生命周期与线程相同:在创建线程时同时创建此线程的虚拟机栈,线程执行结束,虚拟机栈与线程一同被回收

                                    局部变量表 : 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用(4字节)。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。

                                   此区域一共会产生两种异常:

                                           1、若线程请求的栈深度大于JVM允许的深度(-Xss设置栈容量),抛出StackOverFlowError异常(方法递归)(常见于单线程)

                                             2、虚拟机在进行栈的动态扩展时,若无法申请到足够内存,抛出OOM(OutOfMemoryError)异常(常见于多线程)

                  3、本地方法栈

                         本地方法(native方法)执行的内存模型

                           在HotSpot虚拟机中,本地方法栈与虚拟机栈是同一块内存区域。

  1.2、线程共享内存:所有线程共享此类型空间,并且此空间对所有线程可见

               4、堆(GC堆):所有对象都在堆中

                            4.1、Java堆(Java Heap)是JVM管理的最大内存区域。在JVM启动时(执行java   XXX命令是)创建,所有线程共享此内存,此内存中存放的都是对象实例以及数组

                          4.2、Java堆是垃圾回收器管理的最主要内存区域。Java堆可以处于物理上不连续的内存空间。-Xmx设置堆最大值  -Xms设置堆最小值

                           4.3、若堆中没有足够的内存完成对象实例分配并且堆无法再次扩展时,抛出OOM异常

                  5、方法区

                              5.1、用于存储已被JVM加载的类信息常量静态变量等数据。JDK8以前,方法区也叫永久代,JDK8之后称为元空间(Meta Space)

                              5.2、方法区无法满足内存分配需求时,抛出OOM

                                  永久代并不意味着数据进入方法区就永久存在,此区域的内存回收主要是针对常量池的回收以及对类型的卸载。

                    6、运行时常量池

                            6.1、运行时常量池是方法区的一部分,存放字面量(能直接写出来的。如:在Java中所有整形常量是int类型)与符号引用

                              字面量 : 字符串常量(JDK1.7后移动到堆中) 、final常量、基本数据类型的值。

                               符号引用 : 类、字段、方法的完全限定名、 名称、描述符。

                                                类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

 

public class Test {    

         public static void main(String[] args) {  //主方法对应主线程,有一个线程就有一个虚拟机栈

                  Test test = new Test();

                   int a = 10;

           }

}

虚拟机栈中存放了testa

new Test()是对象实例,在堆上

public class Test、public static void main(符号引用在常量池)类的信息在方法区

10:字面量,基本数据类型的常量,在运行时常量池

Test:描述符

对象产生:符号引用——>类——>具体引用

Test test = new Test();  :通过符号引用拿到类信息再new

 

 

OOM:内存溢出:内存中的对象确实还应该存活,但由于对内存不够用产生的异常

内存泄露:无用对象无法被GC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值