JVM虚拟机概念了解

  1. 虚拟机就是一台虚拟的机器,可以分为系统虚拟机和程序虚拟机两种,系统虚拟机是一个完成的操作系统的软件平台; 程序虚拟机就是为 执行单个计算机程序而设计的,比较著名的就是java虚拟机。 常用的系统虚拟机 :visual Box、vmware; 常用的 java程序虚拟机: classic、hotsport等

  2. java虚拟机基本概念了解
    在这里插入图片描述

  • 类加载器:

负责从文件系统中或者网络中加载类和接口信息并赋予唯一的名字,加载的c信息都放到了方法区的空间,

  • Java堆

在java虚拟机启动时建立java堆,几乎所有对象实例都放在java堆中,它是线程共享的,Heap中的对象的内存需要等待GC进行回收。

  • Java虚拟机栈

线程私有内存空间,有局部变量、操作数帧和帧数据区
局部变量:报错函数的参数局部变量
操作数帧:保存中间结果
帧数据区:返回结果异常,异常处理表,方便异常时找到异常代码
每个方法在执行时都会创建一个栈帧用于储存局部变量表、操作数帧、动态链接、方法出口等信息。每个方法从调用直至到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。如果请求的栈的深度大于虚拟机所允许的深度就会抛出stackOverflowError异常(递归调用,递归不是马上返回而是一层层保存,满足添加后才一层层返回),虚拟机栈在动态扩展无法申请到足够的内存就会报outOfMemoryError异常

  • 方法区

存放类信息、类的方法、常量信息、常量池信息还有字符串和数字常量,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。方法区理解为永久区时线程共享的区域。

  • 本地方法栈

依赖于本地方法的实现,如某个JVM实现的本地方法借口使用C连接模型,则本地方法栈就是C栈,可以说某线程在调用本地方法时,就进入了一个不受JVM限制的领域,也就是JVM可以利用本地方法来动态扩展本身。

  • pc寄存器
    每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
    若thread执行Java方法,则PC保存下一条执行指令的地址。若thread执行native方法,则Pc的值为undefined
  • 回收系统

通常我们说的JVM内存回收总是在指堆内存回收,确实只有堆中的内容是动态申请分配的,所以以上对象的年轻代和年老代都是指的JVM的Heap空间,而持久代则是之前提到的MethodArea,不属于Heap。
GC的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停

  • 执行引擎

虚拟机的核心就是执行引擎,它负责处理虚拟机的字节码文件,一般是先编译成机器码在执行

  • 直接内存

java的NIO库允许java使用直接内存从而提高性能,速度优于java堆。

  1. 内存溢出的原理以及处理:OutOfMemoryError
  • OutOfMemoryError: PermGen space(方法区)

【原因】发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。
【解决】解决办法 :增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大 小,XX:MaxPermSize是最大永久保存区域大小。如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

  • OutOfMemoryError:Java heap space(堆内存)

【原因】发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。
【解决】解决办法:增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

  • -OutOfMemoryError:unable to create new native thread(Java栈)

【原因】Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。
【解决】解决办法: 我们可以通过调整jvm参数,降低为每个线程分配的栈内存大小来解决问题,例如在jvm参数中添加-Xss128k将线程栈内存大小设置为128k。

  • java.lang.StackOverflowError

【原因】:这也内存溢出错误的一种,即线程栈的溢出,要么是方法调用层次过多(比如存在无限递归调用),要么是线程栈太小。
【解决】:优化程序设计,减少方法调用层次;调整-Xss参数增加线程栈大小。

猜你喜欢

转载自blog.csdn.net/pengjwhx/article/details/83241997