我对并发编程是个新手,我正在学习它。
我在Java JDK 7 (Fork Join API)中实现了一个快速排序来对一个对象列表(100K)进行排序。
在不使用并发的情况下使用这段递归代码时,我观察到没有内存爆炸,一切都很好。
我只是添加了在多核上使用它的代码(通过扩展类RecursiveAction),然后内存使用量跳得非常高,直到达到它的极限。通过执行一些分析,我观察到线程的创建率很高,我认为这是可以预期的。但是,java线程本身是否需要更多的内存,还是我在这里遗漏了什么?
快速排序必须需要很多线程,但不会比常规对象多。
当我达到阈值时,我是否应该停止创建RecursiveAction线程,然后切换到连续的代码片段(不再有线程)?
非常感谢。
发布于 2010-07-15 06:35:55
Java线程通常占用256k/512k(在操作系统、jdk版本中是常见的)默认情况下,仅使用堆栈空间。
如果你运行的线程比CPU密集型进程(如快速排序)的处理器/核心多,那么你就浪费了大量的资源和速度,所以尽量不要运行比核心多的线程。
发布于 2010-07-15 06:31:10
是的,当工作单元在大约10,000-100,000个操作的范围内时,切换到顺序代码是一个好主意。这只是一个经验法则。因此,对于快速排序,当要排序的大小小于10-20,000个元素时,我会放弃顺序执行,这取决于比较操作的复杂性。
ForkJoinPool的大小是多少-通常它被设置为创建与处理器相同数量的线程,因此您应该不会看到太多线程。如果您手动将并行度设置为高(例如,数百或数千),那么您将看到高(虚拟)内存使用率,因为每个线程都为堆栈分配空间(在32位windows和linux上,默认情况下为256K)。
发布于 2010-07-15 06:50:45
作为CPU限制计算的经验法则,一旦线程的数量超过了可用核心的数量,添加更多的线程并不会加快速度。事实上,由于创建线程的开销、每个线程占用的资源(例如线程堆栈)以及同步的成本,它可能会减慢您的速度。
实际上,即使您有无限数量的内核,也不值得创建线程来完成小任务。即使使用线程池和其他聪明的技巧,如果任务中要完成的工作量太小,使用线程的开销也将超过任何节省的开销。(很难准确预测阈值在哪里,这当然取决于任务的性质以及与平台相关的因素。)
https://stackoverflow.com/questions/3251035
复制相似问题