Java 如何高效地管理C++中的内存/时间?

Java 如何高效地管理C++中的内存/时间?,java,c++,memory,garbage-collection,Java,C++,Memory,Garbage Collection,本案: 我在java中编写了一个MIMPAX算法,然后我用C++移植了代码,并使用了相同的类和方法。然后我对C++代码进行了修改,直到所有的内存泄漏都被修复了,如果可能的话,在Debug中删除函数。当所有漏洞被固定时,我在TIC TAC趾游戏上测试算法,然后代码在C++中被相同地移植。我确信C++版本会更具性能,但是我惊讶地看到,100个不是随机的游戏实例在125秒内被C++版本解决,而java版本在30秒内解决了它们。 然后,使用StaseMealSt1检查两个程序的内存使用情况:测试结束时j

本案:

我在java中编写了一个MIMPAX算法,然后我用C++移植了代码,并使用了相同的类和方法。然后我对C++代码进行了修改,直到所有的内存泄漏都被修复了,如果可能的话,在Debug中删除函数。当所有漏洞被固定时,我在TIC TAC趾游戏上测试算法,然后代码在C++中被相同地移植。我确信C++版本会更具性能,但是我惊讶地看到,100个不是随机的游戏实例在125秒内被C++版本解决,而java版本在30秒内解决了它们。 然后,使用StaseMealSt1检查两个程序的内存使用情况:测试结束时java代码内存使用量增加了大约20%,而C++版本内存只增加了5%。


然后,在我看来,很明显,这个删除策略节省了内存,但降低了时间性能,这不是我想要的,至少在这种情况下是这样。是否有其他删除策略可以更好地设计需要较小运行时间但允许较高内存使用率的软件?

malloc和delete必须做更多的工作

内存不是以多线程方式分配的 内存不是在内存中连续分配的,而是为空闲内存区域分配的。 删除在当前线程中执行。 对于64位应用程序,您可能会发现内存对齐是16字节,而不是8字节,这会导致每次分配更多的填充。 <> C++中的可能解决方案 不要过多地使用堆,在堆栈上分配要比Java或C++的堆快得多,而且它是多线程的。 如果可能的话,一次分配对象块,例如,一个对象数组是C++中的一个分配,而不是java中的N+1。 使用多线程分配器。C++支持多个分配器。 使用竞技场分配模式。如果您有一个包含大量节点的大型数据结构,那么您可以一次分配N个节点的块,当您释放这些节点时,构建一个空闲节点的链接列表。您需要对节点本身执行此操作。在这种方法中,整个数据结构/竞技场一次被释放。 简而言之,如果你把java代码的文字翻译成C++,它可能会慢一些,因为这不利用C++的所有优化,而java却不这样做。
顺便说一句,Java 6+对高达32 GB的内存使用32位引用。如果您构建了一个64位C++应用程序,请看是否使用32位指针/引用/索引是您的选择。

< p> Maloc和Delk必须做更多的工作,作为

内存不是以多线程方式分配的 内存不是在内存中连续分配的,而是为空闲内存区域分配的。 删除在当前线程中执行。 对于64位应用程序,您可能会发现内存对齐是16字节,而不是8字节,这会导致每次分配更多的填充。 <> C++中的可能解决方案 不要过多地使用堆,在堆栈上分配要比Java或C++的堆快得多,而且它是多线程的。 如果可能的话,一次分配对象块,例如,一个对象数组是C++中的一个分配,而不是java中的N+1。 使用多线程分配器。C++支持多个分配器。 使用竞技场分配模式。如果您有一个包含大量节点的大型数据结构,那么您可以一次分配N个节点的块,当您释放这些节点时,构建一个空闲节点的链接列表。您需要对节点本身执行此操作。在这种方法中,整个数据结构/竞技场一次被释放。 简而言之,如果你把java代码的文字翻译成C++,它可能会慢一些,因为这不利用C++的所有优化,而java却不这样做。
顺便说一句,Java 6+对高达32 GB的内存使用32位引用。如果您构建了一个64位C++应用程序,请查看是否使用32位指针/引用/索引是您的选择。 动态分配节点并将其拆下,您将处于 对垃圾收集最有利的情况。你可能想 使用C++的BEHM收集器。IIRC,Boehm的基准, 旨在表明垃圾收集可以比 手动分配,做一些非常类似的事情:构建 大树,然后把它们撕下来

或者,您可以查看某种内存池。 这不是C++初学者的技术,但不是这样。 也很难。或者,不是删除节点,而是将 将它们添加到免费列表中,以便以后回收。分配时 首先查看免费列表,如果是,则只调用new
空的或者将两者结合起来

如果你一直在用很多小树苗建造一棵树 动态分配节点并将其拆下,您将处于 对垃圾收集最有利的情况。你可能想 使用C++的BEHM收集器。IIRC,Boehm的基准, 旨在表明垃圾收集可以比 手动分配,做一些非常类似的事情:构建 那么是大树吗 把他们撕下来

或者,您可以查看某种内存池。 这不是C++初学者的技术,但不是这样。 也很难。或者,不是删除节点,而是将 将它们添加到免费列表中,以便以后回收。分配时 首先查看免费列表,如果是,则只调用new
空的或者将两者结合起来

优化是个棘手的问题,你确定删除会给你带来麻烦吗?你有没有方法来分析你的C++执行时间,以便找到在删除调用上花费的时间?是的,我可以尝试测量删除周期所消耗的时间。我会做的,我会更新你。发布你的代码会有助于分析这个问题。“C++ C++是的,我知道,但是代码包括java和C++的成千上万行。Java和C++是不同的语言。想象一下,你试着用母语保加利亚语逐字直译葡萄牙语;无论一些母语为葡萄牙语的人有多漂亮,结果都不会很好。优化是一个棘手的问题,你确定删除会给你带来那么多麻烦吗?你有没有方法来分析你的C++执行时间,以便找到在删除调用上花费的时间?是的,我可以尝试测量删除周期所消耗的时间。我会做的,我会更新你。发布你的代码会有助于分析这个问题。“C++ C++是的,我知道,但是代码包括java和C++的成千上万行。Java和C++是不同的语言。想象一下,你试着用母语保加利亚语逐字直译葡萄牙语;不管一些母语为葡萄牙语的人有多漂亮,结果都不会很好。我必须建一棵大树。按照您的建议,设计一个节点库是一个好主意,它可以一次分配1000个节点,并根据需要提供minimax算法的参考?@HAL9000如果您不需要回收节点,或者您有一个简单的回收策略,例如,树只需一次添加并释放,这应该会快得多。如果你有大量的delete和malloc的混合,你可能没有一个简单的解决方案。我必须建立一棵大树。按照您的建议,设计一个节点库是一个好主意,它可以一次分配1000个节点,并根据需要提供minimax算法的参考?@HAL9000如果您不需要回收节点,或者您有一个简单的回收策略,例如,树只需一次添加并释放,这应该会快得多。如果您有大量的delete和malloc混合,您可能没有一个简单的解决方案。