专题——JVM

JVM

下图是JDK的结构图(来源于网络)
图片来自网络
不同版本JDK的JRE是不同的,JVM会将相同的字节码文件解析成不同系统识别的0 1 二进制
在这里插入图片描述
JVM 的结构:

由以下代码引入:

public class Demo {
	public static final double PI = 3.14;
	static Circle circle = new Circle();

	public static void main(String[] args) {
		Demo demo = new Demo();
		int c = demo.calculate();
		System.out.println(c);
	}

	public static int calculate() {
		int a = 2;
		int b = 3;
		int c = (a + b) * 2;
		return c;
	}
}

class Circle{
	private double radius;

	public Circle() {
		this(1.0);
	}
	public Circle(double radius){
        this.radius=radius;
    }
}

在这里插入图片描述
为更加好理解栈帧,我们可以通过命令行查看Demo 的字节码文件:

javap -c Demo.class > Demo.txt//-c 为反汇编,可将字节码文件编译成更加容易理解的文件,并写入到 Demo.txt文件中
Compiled from "Demo.java"
public class Demo {
  public static final double PI;

  static Circle circle;

  public Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Demo
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: pop
      10: invokestatic  #4                  // Method calculate:()I
      13: istore_2
      14: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: iload_2
      18: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
      21: return

  public static int calculate();
    Code:
       0: iconst_2
       1: istore_0
       2: iconst_3
       3: istore_1
       4: iload_0
       5: iload_1
       6: iadd
       7: iconst_2
       8: imul
       9: istore_2
      10: iload_2
      11: ireturn

  static {};
    Code:
       0: new           #7                  // class Circle
       3: dup
       4: invokespecial #8                  // Method Circle."<init>":()V
       7: putstatic     #9                  // Field circle:LCircle;
      10: return
}

JVM指令手册可以私聊我发给你们(免费)

堆的结构:
在这里插入图片描述
说明:分代的原因在于提高对象分配内存和垃圾回收的效率,新的对象会放在伊甸园区,当伊甸园区满了之后会由执行引擎进行垃圾回收,即young GC或称minor GC,存活的对象放入S1中,当伊甸园区再次满的时候会再次进行minor GC,这次收集的是伊甸园区和S1中的垃圾,将两个区中都存活的对象再放入S2中,而原先在S1中的对象的分代年龄+1,当伊甸园区再次满的时候再将伊甸园区和S2中存活的对象放入S1中,原先在S2中的对象的分代年龄+1;当一个对象的分代年龄到达15的时候,会被放入老年代,当老年代放满的时候会执行full GC,系统消耗非常高,应尽量避免full GC,一天、一周、一个月进行一次为正常,还有很多规则使对象直接进入老年代,例如其中之一:当Eden中存活的对象大小大于S1的50%时,就直接进入老年代。

JVM调优基础
当输入java -version时
在这里插入图片描述
会出现client或者server两种不同的机制,client机制更多的基于桌面级应用,分配的空间相对比server 少,但是server机制会造成空间浪费,这两种机制可以在jre中修改。

可以进行JVM调优的点:

  1. 选择client还是server机制
  2. 对堆的大小的分配,手动调参数
    例如:-Xms:初始化堆的大小
    -Xmx:最大堆大小
    -XX:New Size:n:设置年轻代的大小
  3. 垃圾收集器的选择

JVM中的垃圾收集器:

在这里插入图片描述
连线表示收集器可以配合使用

serial收集器:唯一一个次收集器,是一个串行收集器,STW(stop the world):收集时暂停整个线程。(图片来自网络)

注意
新生代使用的是复制算法,而老年代使用的是标记-整理算法
在这里插入图片描述
parNew收集器:并行收集器,是CMS默认配合的收集器,多核CPU可以显示出能力,单核和serial效果一样。(图片来自网络)
在这里插入图片描述
parallel :提高吞吐率
系统吞吐率=代码执行时间/(代码执行时间+垃圾收集时间)

CMS收集器:垃圾收集和用户线程并发执行

G1:新生代和老年代的垃圾都可以回收

常用的垃圾回收算法

1.引用计数:

一个对象有一个引用就加1,少一个引用就减1,如果为0就回收,缺点是无法解决循环引用的问题

2.复制算法:

划分为两个相等的区域,只复制正在处理的对象,复制过去可以有序的整理,没有空间碎片,缺点:需要两倍空间

3.标记-清除算法:

第一阶段从引用的根节点开始标记所有被引用的对象,第二阶段遍历整个堆,将为标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。

4.标记-整理算法:

此算法是对标记-清除的优化,使用标记-清除方法清除后,再将存活的对象压入到堆中的一块区域,按顺序排好,解决了标记-清除的内存碎片问题和赋值的空间问题。

以上是自己对JVM所学整理的笔记,不完整,今后会逐步完善!

加油!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值