欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > JVM-Java程序的运行环境

JVM-Java程序的运行环境

2025/2/22 2:04:05 来源:https://blog.csdn.net/weixin_74191696/article/details/145658298  浏览:    关键词:JVM-Java程序的运行环境

Java Virtual Machine Java程序的运行环境

JVM组成
  • 程序计数器

    • 线程私有的,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。
  • Java堆

    • 线程共享的区域: 主要用来保存对象实例, 数组等, 当堆中没有内存空间可分配给实例也无法再扩展时, 则抛出OutOfMemoryError异常
    • 组成: 年轻代+老年代
    • JDK1.7中存在一个永久代, 存储的是类信息, 静态变量, 常量, 编译后的代码
    • JDK1.8移除了永久代, 把数据存储到本地内存的元空间中防止内存溢出
  • 虚拟机栈

    • 每个线程运行时所需要的内存称为虚拟机栈, 先进后出
    • 每个线程只有一个活动栈帧, 对应着当前正在执行的那个方法
    • 栈内存不是越大越好, 栈帧过大会导致线程数变少
    • 栈内存溢出
      • 栈帧过多导致栈内存溢出–递归调用
      • 栈帧过大
  • 运行数据区中的方法区Method Area

    • 方法区是各个线程共享的内存区域, 主要存储类的信息, 运行时常量池, 虚拟机启动时创建, 关闭虚拟机时释放
    • 如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError: Metaspace
    • 常量池:
      • 可以看作一场表, 虚拟机指令根据这张常量表找到要执行的类名, 方法名、参数类型、字面量等信息
      • 运行时常量池: 当类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
  • 直接内存

    • 直接内存并不属于JVM的内存结构, 不由JVM进行管理, 时虚拟机的系统内存,
    • 常见于NIO操作时, 用于数据缓冲区, 他分配回收成本较高, 但读写性能高
类加载器
  • 类加载器
    • 用于装载字节码文件(.class文件)–JVM只会运行二进制文件, 类加载器的作用就是将字节码文件加载到JVM中, 从而让Java程序能够启动起来.
    • 启动类加载器, 扩展类加载器, 应用类加载器(加载开发者自己编写的Java类), 自定义类加载器( 实现自定义类加载规则)
    • 双亲委派模型
      • 加载某一个类, 委托上一级的加载器进行加载, 如果上级加载器也有上级, 则会继续向上委托, 如果该类委托上级没有被加载, 自家在其尝试加载该类
    • 通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性。
    • 为了安全,保证类库API不会被修改
  • 类装载的执行过程
    • 加载
    • ->验证–格式检查, 语法检查
    • ->准备–为类变量分配内存并设置类变量初始值
    • ->解析–把类中的符号引用转换为直接引用
    • ->初始化–对类的静态变量, 静态代码块执行初始化操作
    • ->使用–JVM开始从入口方法执行用户的程序代码
    • ->卸载–当用户程序代码执行完毕后, JVM便开始销毁创建的Class对象
垃圾回收
  • 对象什么时候可以被垃圾回收

    • 引用计数法–引用次数为0时代表这个对象可回收
      • 当对象间出现了循环引用的话, 则引用计数法就会失效
    • 可达性分析算法–利用可达性分析来探索所有存活的对象
  • JVM垃圾回收算法

    • 标记清除算法
      • 标记–可达性分析算法
      • 标记就和清除速度较快, 但内存碎片化
    • 标记整理算法
      • 再标记清除算法前提下, 标记压缩算法多了一步,对象移动内存位置的步骤,其效率也有有一定的影响。
    • 复制算法
      • 将垃圾复制进另一块内存再清理
      • 效率较高, 内存无碎片, 内存使用率较低
  • JVM分代回收

    • 在java8时,堆被分为了两份:新生代和老年代【1:2】
      • 对于新生代,内部又被分为了三个区域。
        • 伊甸园区Eden,新生的对象都分配到这里
        • 幸存者区survivor(分成from和to)
        • Eden区,from区,to区【8:1:1】
    • 在这里插入图片描述
  • JVM垃圾回收器(老年代垃圾, 新生代垃圾)

    • 串行垃圾收集器
    • 并行垃圾收集器
    • 并发CMS垃圾收集器
      • 是一款并发的、使用标记-清除算法的垃圾回收器,
      • 该回收器是针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目标的收集器
    • G1垃圾收集器–作用在新生代和老年代,JDK9后默认使用G1
      • 在这里插入图片描述
  • 引用的区别

    • 强引用–只要所有 GC Roots 能找到,就不会被回收
    • 软引用–需要配合SoftReference使用,当垃圾多次回收,内存依然不够的时候会回收软引用对象
    • 弱引用–需要配合WeakReference使用,只要进行了垃圾回收,就会把弱引用对象回收
    • 虚引用–必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存
JVM实践
  • JVM设置调优

    • 参数如何设置
      • war包部署在tomcat中设置
        • 修改TOMCAT_HOME/bin/catalina.bat文件
      • jar包部署在启动参数设置
        • java -Xms512m -Xmx1024m -jar xxxx.jar
    • 调优参数
      • 对于JVM调优,主要就是调整年轻代、老年代、元空间的内存空间大小及使用的垃圾回收器类型。
      • 设置堆空间大小
      • 虚拟机栈的设置–栈帧大小
      • 年轻代中Eden区和两个Survivor区的大小比例
      • 年轻代晋升老年代阈值设置
      • 垃圾回收收集器–吞吐量设置/收集器选择
    • 调优工具
      • 命令工具
        • jps 进程状态信息, jstack 查看java进程内线程的堆栈信息, jmap 查看堆转信息, jhat 堆转储快照分析工具,jstat 堆转储快照分析工具
      • 可视化工具
        • jsonsole 用于对jvm内存, 线程, 类的健康
        • visualVM 能够监控线程, 内存情况
  • Java内存泄露排查思路

    • 虚拟机栈–StackOverFlowError
    • 方法区–OutOfMemoryError:MetaSpace
    • 堆–OutOfMemoryError:Java heap space
    • 内存泄漏通常是指堆内存,通常是指一些大对象不被回收的情况
      • 通过jmap(程序运行时)或设置jvm参数获取堆内存快照dump
      • 通过工具VisuakVM分析dump文件(VisualVM能够分析离线dump文件)
      • 通过查看对信息的情况, 定位内存溢出的代码
      • 找到对应代码进行修复
  • CPU飙高排查方案与思路

    • 使用top命令查看占用cpu的情况
    • 查案看哪个进程占用cpu较高
    • 使用ps命令查看进程中的线程信息
      看对信息的情况, 定位内存溢出的代码
      • 找到对应代码进行修复
  • CPU飙高排查方案与思路

    • 使用top命令查看占用cpu的情况
    • 查案看哪个进程占用cpu较高
    • 使用ps命令查看进程中的线程信息
    • 使用jstack命令查看进程中哪些线程出现了问题, 最终定位问题

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词