JDK9中的arraylist的add方法联想到JVM方法内联

本文介绍了JDK9中ArrayList的add方法与JVM方法内联的关联。JDK9将add方法拆分以适应-XX:MaxInlineSize参数,该参数限制了可内联方法的最大字节码长度。方法内联是一种优化技术,减少函数调用开销。通过拆分方法,高频操作如ArrayList的add在JDK9中能更好地利用内联优化,提高程序运行效率。
摘要由CSDN通过智能技术生成

今天我不小心看到了jdk9和8中间arraylist的一些小改动。
扩容的方法和逻辑其实大相径庭。
但是一个小细节引起了我的注意。
就是jdk9将jdk8的add方法进行了拆分。

以下是jdk9中的ArrayList相关的add方法。


    /**
     * This helper method split out from add(E) to keep method
     * bytecode size under 35 (the -XX:MaxInlineSize default value),
     * which helps when add(E) is called in a C1-compiled loop.
     */
    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }
    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

以下是1.8

   /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

    /**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

可以看到

/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/

这么一段话。
翻译一下

这个helper方法从add(E)中分离出来,以将方法字节码大小保持在35以下(默认值为-XX:MaxInlineSize),这有助于在C1编译循环中调用add(E)。

然后我就详细了解了一下 这个jvm参数 。

Integer specifying maximum number of bytecode instructions in a method
which gets inlined. 翻译过来是 设置可以被优化的内敛方法的最大的字节码的指令数。

这个时候问题来了,什么是内联优化呢?

方法内联就是把调用方函数代码"复制"到调用方函数中,减少因函数调用开销的技术 函数调用过程
1、首先会有个执行栈,存储它们的局部变量、方法名、动态连接
2、当一个方法被调用,一个新的栈帧会被加到栈顶,分配的本地变量和参数会存储在这个栈帧
3、跳转到目标方法代码执行
4、方法返回的时候,本地方法和参数被销毁,栈顶被移除
5、返回原来的地址执行

https://www.oracle.com/java/technologies/javase/exactoptions-jsp.html

我对于这个玩意儿的大概理解就是说,如果一个方法中调用了另外一个方法,jvm内部会通过方法内联这一优化手段,将两个方法的字节码整合成一个方法。

然后就是上述的 -XX:MaxInlineSize这一参数了。这一参数的默认值是35.
意思就是说,当方法的字节码小于35时,就能触发方法内联。

本身Arraylist的add方法是一个调用频率非常高的方法,在1.8中,这个方法的字节码较长,触发不了方法内联这一优化手段。
所以jdk9中将add方法拆分成了两个方法。

所以我的结论是,尽量将方法拆分的比较细,可以在一定程度上对程序的运行速度有所提升。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值