JVM

一. JVM类加载的双亲委派模型
image
以上图为例,

  1. 当加载String时,App ClassLoader会委托给上级extension ClassLoader/platform ClassLoader加载,而extension ClassLoader/platform ClassLoader会委托给它的父级Bootstrap ClassLoader加载。
    Bootstrap ClassLoader会查找jar/lib/rt.jar的文件,找到了就直接返回。
    2.当加载ext之类的扩展类时,也是由App ClassLoader一层层委托,但是Bootstrap ClassLoader会加载jar/lib/rt.jar的文件没有找到,就会让extension ClassLoader/platform ClassLoader加载,extension ClassLoader/platform ClassLoader会查找jar/ext/lib/rt.jar的文件。找到了就返回。
    3.当加载User之类的开发者自定义的类时,也是由App ClassLoader一层层委托,但是Bootstrap ClassLoader和extension ClassLoader/platform ClassLoader都没有加载到,就会让App ClassLoader加载,如果找到了就返回,如果没有找到,就返回 异常:ClassNotFoundException。
  • 二. 为什么要设计双亲委派模型?
    1. 确保安全,避免Java核心类库被修改。
    1. 避免重复加载。
    1. 保证类的唯一性。
      下面的案例中,会报错
      image
      就是因为Bootstrap ClassLoader类加载器在rt.jar中的String类中没有main方法,所以会报错。
public class String {
  public static void main(String[] args) {
      System.out.println("123");
  }
}

下面下面的案例中,虽然类名改成了MyString,但是包名是java.lang,在Java中也是不允许的。
image

  package java.lang;

  public class MyString {
      public static void main(String[] args) {
          System.out.println("123");
      }
  }

三、内存溢出 OutofMemory
是指程序在申请内存时,没有足够的内存空间供其使用,抛出OutofMemory错误。
比如,申请了8MB空间,但是当前内存可用空间只有5MB,那么就内存溢出。
即,没有空闲的内存,垃圾回收器回收以后也不能提供更多的内存空间。
四、Memory Leak
是指程序运行后,没有释放所占用的内存空间,一次内存泄露可能不会有很大的影响,但长时间的内存泄露,堆积到一定程度就会产生内存溢出。
例如:
1.单例对象,生命周期和应用程序一样长,如果单例对象持有外部对象的引用,那么这个外部对象是不能被回收的,则会产生内存泄露。
2.一些资源未关闭导致,比如数据库连接,网络连接socket和IO流未关闭导致的内存泄露。
五、你们线上项目JVM都是怎么设置的?
假设线上:4核8G机器;

  1. 栈1MB,-xss512k,一个线程是1M,一个线上Tomcat可能有300个线程,是300m。
  2. 堆,把机器的一般内存给堆,4G(新生代、老年代)。
  3. 元空间:一般512M。
    此时JVM参数:
    -Xms4096M -Xmx4096M -Xss1M:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M -XX:+UseG1GC
    六、高并发系统JVM优化
    1、根据并发量、订单类字段计算内存。
    2、对堆、栈、元空间内存进行分配。
    3、Eden和S0、S1的内存是8:1:1。
    4、一般系统例@Service、@Controller注解需要长期存活,一般也不会很多,应该尽快进入老年代。使用该参数MaxTenuringThreshold=5
    5、对于系统中的字典对象这些比较大的可能需要长期存活和使用,让它直接进入老年代。PretenureSizeThreshold=1M
    6、指定合适的垃圾回收期,堆内存大于6G可以使用G1回收器,小于6G使用CMS回收器。
    7、优化思路
    1. 尽可能让对象在新生代分配和回收,避免对象频繁进入老年代导致老年代频繁垃圾回收。
    2. 给系统充足的内存空间,避免新生代频繁垃圾回收。
    3. 指定合适的垃圾回收器。
    注:GC分两种,Minor发生在Eden和S0、S1,full GC发生在老年代
    当老年代的内存达到75%会触发FullGC,FullGC会造成JVM暂停
    一般S0、S1的年龄达到15岁,才会进入老年代。
posted @ 2025-07-08 22:31  Charlie-Pang  阅读(5)  评论(0)    收藏  举报