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中。
相关推荐
記億揺晃着的那天3 分钟前
SpringCloud从零开始简单搭建 - JDK17
java·spring boot·后端·spring cloud·nacos
EPSDA12 分钟前
Java集合(三)
java·开发语言
DC102015 分钟前
Java 每日一刊(第14期):抽象类和接口
java·开发语言
憨憨憨憨憨到不行的程序员15 分钟前
Spring框架基础知识
java·后端·spring
农大蕉蕉18 分钟前
C++校招面经(二)
java·开发语言·c++
尘埃不入你眼眸25 分钟前
递归快速获取机构树型图
java·服务器·windows
项目題供诗28 分钟前
尚品汇-H5移动端整合系统(五十五)
java·服务器·前端
大白要努力!28 分钟前
java 获取集合a比集合b多出来的对象元素
java
咖啡攻城狮Alex29 分钟前
Spring在不同类型之间也能相互拷贝?
java·后端·spring
我明天再来学Web渗透30 分钟前
【hot100-java】【组合总和】
java·开发语言·数据结构·windows·算法·链表·散列表