5

我正在开发一个通过 HTTP 流式传输音乐的 Java 应用程序,我遇到的一个问题是,当应用程序从磁盘读取音频文件并将其发送到客户端时,它通常会使 CPU 达到 90-100 %(这可能会导致用户在运行其他应用程序时出现问题)。

是否可以控制执行此工作的线程以使用更少的 CPU,或者这是否需要由操作系统控制?目前是否有任何技术可以管理您的应用程序的密集程度?

我知道您可以以高/低优先级启动线程,但这在这种情况下似乎对我没有任何影响。

(我无法忘记“我已经要求计算机做某事,所以它显然会尽可能快地完成它......”)

谢谢!

竿。

4

9 回答 9

6

该任务(从磁盘读取文件并通过 HTTP 发送)不应使用任何大量 CPU,尤其是在音乐流所需的比特率下(除非您正在谈论多通道未压缩 PCM 或类似的东西,但是即使这样,它也应该是 I/O-bound 并且不使用大量 CPU)。

您可能正在以一种非常低效的方式进行读/写。您是分别读/写每个字节还是使用某种缓冲区?

于 2009-01-21T08:20:27.017 回答
2

我会检查你正在使用多少缓冲。如果您一次读/写一个字节,您将消耗大量 CPU。但是,如果您正在读取/写入 4 kB 的块,则根本不应该使用太多 CPU。如果您的网络是互联网,那么您的 CPU 不应超过单个客户端的 10%。

缓冲区大小的一种近似值是带宽 * 延迟。例如,如果您希望用户以 500 KB/s 的速度进行流式传输,并且网络延迟高达 0.1 秒,那么缓冲区大小应该在 50 KB 左右。

于 2009-01-21T21:40:55.857 回答
2

您可以使用 Thread 中的方法降低它的优先级(如有必要,通过 Thread.currentThread() )。

您还可以在它的处理循环中放置延迟(Thread.sleep())。

除此之外,让操作系统来处理它。如果您的程序可以使用 100% CPU,并且没有其他东西需要 CPU,那么您的应用程序不妨使用它,而不是让 O/S 空闲任务拥有它。

流数据确实应该是 I/O 绑定的,因此您绝对应该查看在读取数据和发送数据之间所做的工作。例如,您是否正在逐字节读取/发送无缓冲?

编辑:针对 marr75 的评论,我绝对不主张您编写浪费CPU 资源的糟糕、低效的代码 -我的网站上有一篇文章清楚地传达了我对这种思维方式的看法。相反,我要说的是,如果您的代码合法地需要 CPU,并且如果用户想要做其他事情,您已经优先考虑让它表现得很好,那么人为地延迟结果只是为了避免挂钩是没有意义的CPU——这只会对用户造成伤害,让他们等待更长时间等待最终结果,他们可能希望尽快获得最终结果。

于 2009-01-21T08:03:19.330 回答
1

您是否有以下一项或多项:

  • 软件 RAID
  • 压缩文件夹
  • 侵入式病毒检查器
  • 环回文件系统
于 2009-01-21T20:09:50.347 回答
0

好的,谢谢大佬们的建议!看起来我只需要考虑尝试提高我的应用程序流式传输方式的效率(尽管不确定这会走多远,因为我基本上只是从磁盘读取文件并将其写入客户...)。

于 2009-01-21T20:04:34.443 回答
0

VisualVM 很容易用于找出你的 CPU 时间花在了 Java 应用程序上,它包含在最新版本的 JDK 中(在 Windows 上名为 jvisualvm.exe)

于 2009-01-21T20:13:18.063 回答
0

除了上面给出的信息之外:JVM 在如何使用操作系统线程方面是自由的。Java 应用程序中的线程可能在单独的操作系统线程中运行,或者它可能与其他线程共享该线程。查看您正在使用的 JVM 的文档以获取更多信息。

于 2009-01-21T09:14:05.880 回答
0

跟进我的“深思熟虑的缓冲区”评论,这是 TCP 缓冲的一个很好的经验法则,缓冲区大小 = 2 * 带宽 * 延迟

因此,如果您想流式传输 214kbps 的音乐(大约 27kB/s)并且有 60ms 的延迟,那么您正在查看 3.24 KB,并且四舍五入到一个不错的 4kB 缓冲区将非常适合您在广泛的范围内使用系统。

于 2009-06-26T17:15:36.600 回答
0

我认为您不能在不丢失功能(流音乐)的情况下降低优先级。您的程序从操作系统获得了这么多 CPU,因为它需要它。这不像操作系统无缘无故地放弃 cpu 时间,或者因为“它有心情”。

如果您认为,您可以在不使用那么多 cpu 利用率的情况下完成任务,您可以分析您的应用程序并找出这种高 cpu 利用率发生在哪里,然后尝试改进您的代码。

我认为您正在以低效的方式进行流式传输,但我说流式传输可以是一项高度利用的任务。

我再说一遍,不要考虑通过降低进程的优先级或告诉操作系统“不要给这个进程太多的 cpu 时间”来降低 cpu 利用率。在我看来,这完全是错误的直觉。通过在分析后改进算法和代码来降低 CPU 使用率。

本文是分析 java 的一个良好开端:http: //www.ibm.com/developerworks/edu/os-dw-os-ecl-tptp.html

于 2009-01-21T08:34:38.097 回答