当前位置: 首页 > 面试题库 >

除了互斥锁或垃圾回收以外,还有哪些机制可以减慢我的多线程Java程序?

慕震博
2023-03-14
问题内容

问题

我有一段Java代码(如果相关,则为JDK 1.6.0._22),可实现无互斥的无状态,无副作用的功能。但是,它确实占用大量内存(我不知道这是否相关)。

过去,我曾访问过Sun
Laboratories,并收集了标准的“性能与线程数”曲线。由于此函数没有互斥体,因此它具有一个不错的图形,尽管随着线程数量的增加,垃圾回收也开始了。经过一些垃圾收集调整之后,我能够使该曲线几乎平坦。

我现在在Intel硬件上进行相同的实验。硬件有4个CPU,每个CPU都有8个内核和超线程。这给出了64个availableProcessors()。不幸的是,“性能与线程数”的曲线很好地缩放了1、2、3个线程,上限为3个线程。3个线程之后,我可以根据需要为任务分配尽可能多的线程,而性能却没有任何改善

尝试解决问题

我最初的想法是我很愚蠢,并在某个地方引入了一些同步代码。通常,要解决此问题,我运行JConsole或JVisualVM,并查看线程堆栈跟踪。如果我有64个线程以3的速度运行,那么我希望其中有61个线程正等待输入互斥体。我没找到这个。相反,我发现所有线程都在运行:非常缓慢。

第二个想法是,时间框架可能会引入问题。我用一个虚拟函数替换了我的函数,使用AtomicLong可以算出十亿。这可以通过线程数进行漂亮的扩展:使用64个线程比使用1个线程,我可以算出10倍10,000倍的10,000倍。

我以为(绝望的开始)垃圾回收确实花费了很长时间,所以我调整了垃圾回收参数。尽管这改善了我的延迟变化,但对吞吐量没有影响:我仍然有64个线程以我希望3的速度运行。

我已经下载了英特尔工具VTunes,但是我的技能很弱:它是一个复杂的工具,我还不了解。我收到了订购书:给自己一个有趣的圣诞节礼物,但是为时不晚,无法解决我当前的问题

  1. 我可以使用哪些工具(心理或软件)来加深对正在发生的事情的了解?
  2. 除了互斥锁或垃圾回收以外,还有哪些机制可能会降低我的代码速度?

问题答案:

后来的许多实验中,我发现JVM没什么作用,但我也发现了JDump的强大功能。64个线程中的50个位于以下行。

java.lang.Thread.State: RUNNABLE
    at java.util.Random.next(Random.java:189)
    at java.util.Random.nextInt(Random.java:239)
    at sun.misc.Hashing.randomHashSeed(Hashing.java:254)
    at java.util.HashMap.<init>(HashMap.java:255)
    at java.util.HashMap.<init>(HashMap.java:297)

Random.next看起来像这样

 protected int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
 }

最有趣的是,这并不是一个明显的锁,因此我用来发现互斥锁的工具无法正常工作。

因此,似乎任何Java哈希图的创建都会导致应用程序停止可伸缩性(我夸大了但不多)。我的应用程序确实大量使用了哈希图,所以我想我要么重写哈希图,要么重写应用程序。

我在提出一个单独的问题,以查看如何处理。

谢谢你的帮助



 类似资料:
  • 问题内容: 是多线程/进程编程的新手。所以这是我需要澄清的。 处理代码 使用上述伪代码,如果互斥锁未解锁,进程B是否可以访问? 如何从进程B正确访问sharedResource? 有没有清晰的可视化图表说明互斥体,线程和进程之间的关系? 问题答案: 您需要做的是调用pthread_mutex_lock来保护互斥锁,如下所示: 一旦执行此操作,在您在该线程中进行调用之前,不会再进行任何其他调用。因此

  • 本文向大家介绍js垃圾回收的方式有哪些?相关面试题,主要包含被问及js垃圾回收的方式有哪些?时的应答技巧和注意事项,需要的朋友参考一下 从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。

  • 本文向大家介绍Python垃圾回收机制?相关面试题,主要包含被问及Python垃圾回收机制?时的应答技巧和注意事项,需要的朋友参考一下 引用计数 标记清除 分代回收  

  • 本文向大家介绍JS的垃圾回收机制?相关面试题,主要包含被问及JS的垃圾回收机制?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: GC(garbage collection),GC执行时,中断代码,停止其他操作,遍历所有对象,对于不可访问的对象进行回收,在V8引擎中使用两种优化方法, 分代回收,2、增量GC,目的是通过对象的使用频率,存在时长来区分新生代和老生代对象,多回收新生代区,少回收老

  • 说一下 jvm 有哪些垃圾回收器?

  • 类型 pthread_mutex_t 互斥锁基本操作 函数 描述 [[pthread_mutex_init pthread_mutex_init]] 初始化互斥锁 [[pthread_mutex_lock pthread_mutex_lock]] 阻塞申请互斥锁 [[pthread_mutex_unlock pthread_mutex_unlock]] 释放互斥锁 [[pthread_mutex_