Java是否会自动并行化递归函数?

时间:2018-11-08 20:18:01

标签: java recursion parallel-processing

我正在并行处理一个递归函数,并且测得不良的加速比。在调试代码时,我注意到在顺序版本中,所有内核都可以正常工作。

在一个最小的示例中,我重现了这种行为,同样,我所有的内核的工作量约为90%。我正在使用Java 8(OpenJDK)。

Java是否在我不知情的情况下自动进行并行处理? Java如何做到这一点?

import java.util.Random;
import java.util.ArrayList;

class Node
{
    float value;
    ArrayList<Node> children;

    public Node()
    {
        children = new ArrayList<Node>();
    }

    public Node(float value)
    {
        this.value = value;
    }

    public int count()
    {
        int count = 1;

        if (children != null)
            for (Node c : children)
                count += c.count();

        return count;
    }
}

public class ProofOfConcept {
    final static int N_NODES = 10000000;
    final static int MAX_CHILDREN = 6;

    final static Random RAND = new Random();

    static Node generateTree(int nNodes)
    {
        if (nNodes > 1)
        {
            Node result = new Node();
            int nChildren = 1 + RAND.nextInt(Math.min(MAX_CHILDREN, nNodes) - 1);
            int nNodesPerChild = (nNodes - 1) / nChildren;

            for (int i = 0; i < nChildren; ++i)
            {
                Node t = generateTree(nNodesPerChild);
                result.children.add(t);
            }

            return result;
        }
        else
            return new Node(RAND.nextFloat());
    }

    public static void main(String[] args)
    {
        Node t = generateTree(N_NODES);
        System.out.println(t.count());
    }
}

编辑:这对我来说真的也很奇怪。我附上了htop的屏幕快照;如您所见,我们有主进程和八个线程(每个逻辑内核一个)。

htop

编辑2:似乎GC正在并行执行其工作。对于那些不明白为什么如果显然没有任何对象被释放的情况下触发GC的人,您应该阅读following reference

  

当分配失败触发垃圾回收,但是垃圾回收没有释放足够的空间时,垃圾回收器将扩展存储堆。在堆扩展期间,垃圾收集器将从为堆保留的最大存储量(由-Xmx选项指定的量)中获取存储,并将其添加到堆的活动部分(从-指定的大小开始) Xms选项)。堆扩展不会增加JVM所需的存储量,因为-Xmx选项指定的最大存储量已在启动时分配给JVM。如果-Xms选项的值在堆的活动部分为应用程序提供了足够的存储空间,则垃圾收集器完全不必进行堆扩展。

1 个答案:

答案 0 :(得分:6)

不,Java并非神奇地使您的代码并行化。

如果看到所有核心上的利用率都达到90%,则是操作系统,其他进程或JVM在做后台工作。可能是使用并行GC并利用所有内核收集垃圾的JVM。