【问题标题】:Java: Thread local memory allocation and scalabilityJava:线程本地内存分配和可扩展性
【发布时间】:2016-04-21 08:31:22
【问题描述】:

我正在尝试提高 Java 应用程序的可伸缩性,该应用程序在单独的线程中处理多个小任务。但它显示出意想不到的糟糕结果。似乎内存分配根本不可扩展。这很奇怪,因为对象是为每个线程在本地分配的。 Java 内存管理器应该能够在线程的本地堆中分配它们而无需全局锁定。 GC 线程没有显示任何重要的活动。 有一个简单的测试:

private static class AllocTest implements Runnable
{
    @Override
    public void run()
    {
        for (int i = 0; i < 100000; ++i)
        {
            char[] s = new char[100];
        }
    }
}

final int THREADS_COUNT = 4;
    LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>(THREADS_COUNT);
    ThreadFactory threadFactory = Executors.defaultThreadFactory();
    ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_COUNT, THREADS_COUNT, 1, TimeUnit.HOURS, taskQueue, threadFactory);
    pool.prestartAllCoreThreads();

    long startTime = System.nanoTime();
    for (int i = 0; i < 1000; ++i)
    {
        pool.getQueue().offer(new AllocTest(), 1, TimeUnit.MINUTES);
    }
    pool.shutdown();
    pool.awaitTermination(1, TimeUnit.HOURS);
    long endTime = System.nanoTime();
    System.out.print("Elapsed time: ");
    System.out.print(TimeUnit.NANOSECONDS.toMillis(endTime - startTime));

将线程数 (THREADS_COUNT) 从 1 更改为 4,我得到几乎相同的结果: THREADS_COUNT 个时间

  1. 4811
  2. 4783
  3. 4814
  4. 4823

测试使用“-server”VM 标志运行。 Java 版本 - 1.8.0_66。 在平台上试用 - Windows 7 x64(1 个处理器,8 个内核)、SunOS 5.10 x64(2 个处理器,8 个内核)。

我将不胜感激对此类行为的任何解释或关于如何获得更好的可扩展性的建议(例如,一些特定的 jvm 设置)。

编辑:我知道引入一些线程本地池来重用对象而不是每次都分配它应该可以提高可伸缩性。但这只是解决方法(我目前正在尝试实施)。我实际上想找到这两个问题的答案:1)为什么提供的测试不可扩展? 2)如果不是硬件限制,在这种情况下如何让jvm高效工作而无需更改代码?

【问题讨论】:

  • 你确定内存是从堆中分配的吗?使用如此简单的代码,Java 编译器应该能够确定内存可以从堆栈中分配,甚至根本不分配。
  • 我认为在这种情况下“经过的时间”将接近 0
  • @james large OK,但至少有 TLAB 之类的东西:线程本地分配缓冲区。用于快速分配堆空间而无需同步
  • 点了。评论已撤消。
  • @VladimirP:嗯,刚刚注意到它需要相当长的时间(4.8 秒)来完成它正在做的任何事情,所以它一定是在做某事。我已经删除了我的答案。

标签: java multithreading memory-management scalability


【解决方案1】:

看起来分配速度非常接近我的 RAM 的理论最大值。 Java 甚至在 1 个线程中就达到了它,因此使用更多线程并没有更好。此外,我发现我的 PC 配置为在单通道模式下使用内存(两个 RAM 模块安装到不同颜色的插槽中)。在双模式下,我观察到两倍的效果。

附:谢谢大家的想法!

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 2018-05-18
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多