37

我想为 Java 低延迟应用程序创建全面的清单。你能在这里添加你的清单吗?

这是我的清单
1. 使您的对象不可变
2. 尝试减少同步方法
3. 锁定顺序应该有据可查,并小心处理
4. 使用分析器
5. 使用 Amdhal 定律,并找到顺序执行路径
6. 使用 Java 5并发实用程序和锁
7. 避免线程优先级,因为它们依赖于平台
8. 可以使用 JVM 预热
9. 更喜欢不公平的锁定策略
10. 避免上下文切换(许多线程会导致适得其反)
11. 避免装箱、拆箱
12. 注意编译器警告
13. 线程数应等于或小于内核数

低延迟应用程序每毫秒调整一次。

4

12 回答 12

8

尽管不变性很好,但它不一定会改善延迟。确保低延迟可能取决于平台。

除了一般性能之外,GC 调优也非常重要。减少内存使用将有助于 GC。特别是如果您可以减少需要移动的中年对象的数量 - 让它保持长期或短期的对象。还要避免任何接触烫发的东西。

于 2010-04-04T14:36:35.703 回答
6

避免装箱/拆箱,尽可能使用原始变量。

于 2010-04-06T06:56:49.580 回答
5

在消息处理路径上尽可能避免上下文切换后果:使用 NIO 和单个事件循环线程(反应器)

于 2010-05-10T15:51:05.973 回答
4

避免广泛的锁定和多线程,以免破坏现代处理器(及其缓存)中的增强功能。然后,您可以使用单线程达到令人难以置信的极限(每秒 600 万次事务),并且延迟非常低。

如果你想查看一个真实世界的低延迟 Java 应用程序,并了解其架构的足够详细信息,请查看 LMAX:

LMAX 架构

于 2014-05-15T04:41:42.420 回答
4

购买、阅读和理解 Effective Java。也可以在线获取

于 2010-04-04T14:10:58.970 回答
3

测量,测量和测量。使用尽可能接近真实数据和接近生产硬件的数据来定期运行基准测试。低延迟应用程序通常被更好地视为设备,因此您需要考虑部署的整个盒子,而不仅仅是特定的方法/类/包/应用程序/JVM 等。如果您没有在生产环境等设置上构建现实的基准测试,您将在生产。

于 2013-01-06T13:36:35.473 回答
1

不要在应用程序中安排比底层硬件上的内核更多的线程。请记住,操作系统将需要线程执行和可能共享相同硬件的其他服务,因此您的应用程序可能需要使用少于可用内核的最大数量。

于 2012-08-31T14:59:36.127 回答
1
  • 考虑使用非阻塞方法而不是同步。
  • 考虑在阻塞数据结构和锁上使用易失性或原子变量。
  • 考虑使用对象池。
  • 使用数组而不是列表,因为它们对缓存更友好。
  • 通常,由于锁定以及内存和缓存访问延迟,将数据发送到其他内核的小任务可能比在单个内核上处理要花费更多时间。因此,考虑通过单个线程处理任务。
  • 降低访问主存的频率并尝试使用缓存中存储的数据。
  • 考虑选择专注于性能优化的服务器端 C2 JIT 编译器,而不是专注于快速启动时间的 C1。
  • 当不同线程使用的两个字段可以位于单个缓存行上时,请确保您没有错误的对象字段共享。
  • 阅读https://mechanical-sympathy.blogspot.com/
  • 考虑使用 UDP over TCP
于 2020-05-04T22:14:21.907 回答
0

另一个重要的想法是首先让它工作,然后测量性能,然后隔离任何瓶颈,然后优化它们,然后再次测量以验证改进。

正如 Knuth 所说,“过早的优化是万恶之源”。

于 2010-04-21T21:20:01.920 回答
0

在生成大字符串时使用StringBuilder而不是。String例如查询。

于 2010-04-04T14:06:21.323 回答
0

除了这里已经建议的开发人员级解决方案之外,考虑加速 JIT 运行时(例如 Zing)和堆外内存解决方案(如 Teracotta BigMemory、Apache Ignite)也非常有益,以减少 Stop-the-world GC 暂停。如果某些 GUI 涉及使用像 Hessian 这样的二进制协议,ZERO-C ICE 而不是 webservice 等是非常有效的。

于 2018-01-03T01:38:39.600 回答
0

我认为“仅在适当的情况下使用可变对象”比“使您的对象不可变”更好。许多非常低延迟的应用程序都有他们重用的对象池以最小化 GC。不能以这种方式重用不可变对象。例如,如果您有一个 Location 类:

class Location {
    double lat;
    double lon;
}

您可以在启动时创建一些并一遍又一遍地使用它们,这样它们就不会导致分配和后续的 GC。

不过,这种方法比使用不可变位置对象要复杂得多,因此只能在需要时使用。

于 2016-04-12T14:08:16.370 回答