JVM相关

JVM的类加载过程

JVM的类加载过程包括加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)五个阶段,具体如下:

  1. 加载(Loading):加载是类加载过程的第一个阶段,它的主要任务是通过类加载器将类的字节码文件加载到内存中,并生成一个代表该类的 java.lang.Class 对象。类加载器会根据类的全限定名来定位并读取类文件,然后将类的字节码数据转换为方法区的运行时数据结构。

  2. 验证(Verification):在验证阶段,虚拟机将对加载的类进行各种验证,以确保类文件的字节流符合虚拟机的规范要求,防止恶意代码或错误的字节码文件影响虚拟机的正常运行。

  3. 准备(Preparation):在准备阶段,虚拟机为类的静态变量分配内存,并设置默认初始值,这些变量存储在方法区中。注意,此时不会为实例变量分配内存,实例变量会在对象实例化时随着对象一起分配在堆内存中。

  4. 解析(Resolution):解析阶段是将常量池中的符号引用替换为直接引用的过程。解析阶段可能在初始化之前或初始化过程中进行。

  5. 初始化(Initialization):初始化阶段是类加载过程的最后一个阶段,此阶段是真正执行类中定义的Java程序代码(静态变量赋值、静态代码块等)的阶段。当一个类被初始化时,其父类也会被初始化,但接口并不会被初始化。类初始化阶段是线程安全的,多个线程同时初始化一个类时,只会有一个线程执行初始化,其他线程会被阻塞。

总的来说,类加载过程是JVM将类加载到内存并准备好供程序运行所需的各种数据结构的过程,它确保了Java程序的正确性和安全性。

JAVA内存泄露

内存泄露的常见原因

  • 资源未释放
    程序中使用的资源(比如文件、数据库连接、网络连接等)未被正确释放或关闭,这些资源所占用的内存将无法被垃圾回收机制释放。如果程序中频繁创建资源却不释放或者忘记释放资源,将会导致内存泄漏问题。
  • 内部类持有外部类
    如果有地方引用了这个非静态内部类,会导致外部类也被引用,即使外部类已经没有其他地方在使用了,垃圾回收时也无法回收这个外部类
  • ThreadLocal的内存泄露
    ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。
    ThreadLocal正确的使用方法
    每次使用完ThreadLocal都调用它的remove()方法清除数据
    将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉 。

内存泄露的影响

资源不释放,随着时间增加,内存占用也会增加,导致系统性能下降,出现卡顿或响应缓慢等问题系统资源耗尽最终导致内存溢出。

问题排查

如果线上出了问题,首先判断是业务问题还是整个系统的问题。如果是业务问题,就去看应用的日志等进行排查。如果出现了如下问题,就可能是整个系统的问题:

  1. 大量接口都很慢
  2. 页面打不开
  3. 是否CPU占用过高
  4. 是否内存占用过高
  5. 是否磁盘占用过高
  6. 是否网络故障
  7. 查看后台日志
  8. 是否是数据库问题(比如:索引失效、死锁)
  9. 是否是垃圾回收导致
  10. 是否死锁等

Java线上服务问题处理 java线上问题排查

JVM的调优

  • Xms
    初始堆大小。
  • Xmx
    最大堆大小。
    一般将Xms和Xmx设为一样的值,若-Xms比较小,又需要初始化很多对象,jvm就必须反复增加内存。一样大也可避免每次垃圾回收完成后JVM重新分配内存。
  • Xss
    线程的栈的大小。
  • XX:NewSize=n
    设置年轻代大小
  • Xmn
    设置年轻代初始大小和最大大小。增大年轻代后,会减小年老代大小,此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
    等效于: 使用 -XX:NewSize 设置初始化大小并使用-XX:MaxNewSize 设置最大大小。
  • XX:NewRatio=n
    设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
  • XX:SurvivorRatio=n
    年轻代中Eden区与两个Survivor区的比值。
  • XX:MetaspaceSize=n
    元空间大小。
  • XX:MaxMetaspaceSize=n
    最大元空间大小。

java四种引用类型

  • 强引用
    强引用是使用最普遍的引用,我们写的代码,99.9999%都是强引用
    只要某个对象有强引用与之关联,这个对象永远不会被回收,即使内存不足,JVM宁愿抛出OOM,也不会去回收。
  • 软引用
    只有在内存不足时,JVM才会回收该对象。
    当内存不足时,会触发JVM的GC,如果GC后,内存还是不足,就会把软引用包裹的对象给干掉。
  • 弱引用
    不管内存是否足够,只要发生GC,弱引用就会被回收。
  • 虚引用
    无法通过虚引用来获取对一个对象的真实引用。
    虚引用必须与ReferenceQueue一起使用。当GC准备回收一个对象时,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。

相关推荐

  1. JVM相关

    2024-03-13 07:32:01       41 阅读
  2. jvm相关

    2024-03-13 07:32:01       40 阅读
  3. JVM相关面试题

    2024-03-13 07:32:01       42 阅读
  4. jvm相关知识点

    2024-03-13 07:32:01       70 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-13 07:32:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-13 07:32:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-13 07:32:01       82 阅读
  4. Python语言-面向对象

    2024-03-13 07:32:01       91 阅读

热门阅读

  1. flink状态后端和检查点的关系

    2024-03-13 07:32:01       49 阅读
  2. 【嵌入式DIY实例】-DIY锂电池电压检测表

    2024-03-13 07:32:01       45 阅读
  3. 字节一面:TCP 和 UDP 可以使用同一个端口吗?

    2024-03-13 07:32:01       39 阅读
  4. HQL 55 题【持续更新】

    2024-03-13 07:32:01       41 阅读
  5. django学习笔记

    2024-03-13 07:32:01       44 阅读
  6. Pandas教程:DataFrame删除重复的行数据

    2024-03-13 07:32:01       48 阅读
  7. uniapp实现点击选项跳转到应用商店进行下载

    2024-03-13 07:32:01       46 阅读