JVM调优-最简单的JVM调优方式

45 阅读2分钟

JVM调优

JVM内存的分代划分

image-20230326143205421.png

活跃数据300M:

总堆:300M*4 = 1.2G; 新生代 = 450M; 老年代 = 750M

扩容新生代能提高GC效率吗?

image-20230326144331019.png

所以说,JVM最简答的优化方式:Eden区容量加大

因为复制算法只复制存活的对象,而增大Eden区容量,延迟MinorGC间隔,就会有相当一部分对象在GC前就不存活了,就能有效的减少复制操作的耗时。

JVM是如何避免Minor GC时扫描全堆的呢?

出现全堆扫描的情况是由于出现了跨代引用的情况,就是新生代引用了老年代的对象或者老年代引用了新生代的对象。为了避免全堆扫描这样耗时的操作,JVM设置了card table(卡表(数组))来记录跨代引用情况(以空间换时间的操作),这样扫描的时候只需要扫描跨代引用的duty data就可以了,从而避免全堆扫描

常量池

  • Class常量池(静态常量池)
  • 运行时常量池
  • 字符串常量池

字符串常量池

String —— JDK1.8

String类分析

String的创建方式

分配内存的方式

方法一(推荐)

image-20230326161807315.png

public void mode1(){
    String str = "abc";
    String str1 = "abc";
    System.out.print("str == str1: ");
    System.out.println(str == str1);//true
}

方法二(不推荐):操作有点多余了

image-20230326162554252.png

方式三

image-20230326162927497.png

方式四:new String("").intern() 方法创建会查询字符串常量池是否有对应的对象

	public void mode6(){
        //去字符串常量池找到是否有等于该字符串的对象,如果有,直接返回对象的引用
        String a = new String("king").intern(); // new 对象、king 字符串常量池创建
        String b = new String("king").intern(); // b == a
        
        //test-------------
//        String a = new String("king"); // new 对象、king 字符串常量池创建
//        String b = new String("king"); // b != a
        if (a == b){
            System.out.println("a == b");
        }else {
            System.out.println("a != b");
        }
    }

Java8、Java11是长期稳定版本