JVM四种方法调用指令以及区分非虚方法和虚方法

一 虚方法和非虚方法

如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的。这样的方法称为非虚方法。

静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法。

其他方法称为虚方法。

子类对象的多态的使用前提

  • 类的继承关系
  • 方法的重写

二 虚拟机中提供了以下几条方法调用指令

1 普通调用指令

  • invokestatic:调用静态方法,解析阶段确定唯一方法版本。它对应的是非虚方法。

  • invokespecial:调用<init>方法、私有及父类方法,解析阶段确定唯一方法版本。它对应的是非虚方法。

  • invokevirtual:调用所有虚方法。final 修饰的方法是非虚方法。final 修饰除外的方法是虚方法。

  • invokeinterface:调用接口方法。它对应的是虚方法。

2 动态调用指令

  • invokedynamic:动态解析出需要调用的方法,然后执行。

前四条指令固化在虚拟机内部,方法的调用执行不可人为干预,而 invokedynamic 指令则支持由用户确定方法版本。其中 invokestatic 指令 和invokespecial 指令调用的方法称为非虚方法,其余的(final修饰的除外)称为虚方法。

三 实战

1 代码

/**
* 解析调用中非虚方法、虚方法的测试
* invokestatic 指令和 invokespecial 指令调用的方法称为非虚方法
*/
class Father {
    public Father() {
        System.out.println("father的构造器");
    }

    public static void showStatic(String str) {
        System.out.println("father " + str);
    }

    public final void showFinal() {
        System.out.println("father show final");
    }

    public void showCommon() {
        System.out.println("father 普通方法");
    }
}

public class Son extends Father {
    public Son() {
        // invokespecial
        super(); // 非虚方法
    }

    public Son(int age) {
        // invokespecial
        this(); // 非虚方法
    }

    // 不是重写的父类的静态方法,因为静态方法不能被重写!
    public static void showStatic(String str) {
        System.out.println("son " + str);
    }

    private void showPrivate(String str) {
        System.out.println("son private" + str);
    }

    public void show() {
        // invokestatic
        showStatic("atguigu.com");  // 非虚方法
        // invokestatic
        super.showStatic("good!"); // 非虚方法
        // invokespecial
        showPrivate("hello!"); // 非虚方法
        //invokespecial
        super.showCommon(); // 非虚方法

        // invokevirtual
        showFinal(); // 因为此方法声明有 final,不能被子类重写,所以也认为此方法是非虚方法。

        // 虚方法如下:
        // invokevirtual
        showCommon(); // 虚方法
        info(); // 虚方法

        MethodInterface in = null;
        // invokeinterface
        in.methodA(); // 虚方法
    }

    public void info() {
    }

    public void display(Father f) {
        f.showCommon();
    }

    public static void main(String[] args) {
        Son so = new Son();
        so.show();
    }
}

interface MethodInterface {
    void methodA();
}

2 测试结果

father的构造器

son atguigu.com

father good!

son privatehello!

father 普通方法

father show final

father 普通方法

Exception in thread "main" java.lang.NullPointerException

    at com.atguigu.java2.Son.show(Son.java:65)

    at com.atguigu.java2.Son.main(Son.java:77)

3 图解

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java虚拟机(JVM)调优主要有以下几种方法: 1. 堆内存调优:JVM的堆内存是用来存储对象的地方,可以通过调整堆内存的大小来提升性能。一般来说,应该根据应用程序的需求和服务器的硬件配置来合理地分配堆内存大小。如果堆内存太小,可能会导致频繁的垃圾回收,降低性能;如果堆内存太大,可能会导致内存浪费。 2. GC调优:GC(垃圾回收)是JVM管理内存的机制。通过调整GC算法和参数,可以优化内存的回收和释放。常见的GC算法有串行GC、并行GC、CMS GC、G1 GC等,可以根据应用程序的特点选择合适的GC算法,以获得更好的性能。另外,还可以通过设置GC参数(如-Xms、-Xmx、-XX:NewRatio等)来优化GC过程。 3. 线程调优:JVM中的线程是执行程序的基本单位。通过合理管理和调优线程,可以提高程序的并发性能。例如,可以通过合理地使用线程池、减少线程的创建和销毁、降低线程的阻塞时间等来提升性能。 4. 内存分析工具调优:使用内存分析工具(如VisualVM、Eclipse Memory Analyzer等),可以监测应用程序的内存使用情况,并识别内存泄漏和性能瓶颈。通过分析工具提供的信息,可以定位问题并采取相应的优化措施。 综上所述,JVM调优主要包括堆内存调优、GC调优、线程调优和使用内存分析工具进行优化。根据具体的应用场景和问题,可以结合这些方法来提高Java应用程序的性能和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值