我用C编写了一个库,它消耗了大量的内存(数百万个小块)。我编写了一个使用这个库的c程序。我还编写了一个使用同一个库的java程序。Java程序在库周围是一个非常薄的层。基本上,只有一个本地方法被调用,完成所有的工作并在数小时后返回。Java与本机库之间不再使用java调用接口进行通信。也没有使用大量内存的Java对象。
所以c程序和Java程序非常相似。整个计算/内存分配都发生在本机库中。还是这样。执行时,c程序消耗3GB内存。但是Java程序消耗4.3GB!(由top报告的VIRT金额)
我检查了Java进程的内存映射(使用pmap)。库只使用40 by。因此,由Java加载的额外库并不是原因。
有人对这种行为有什么解释吗?
编辑:到目前为止,感谢您的回答。让它更清楚一点: java代码只会调用原生库(一次)!java堆是标准大小(可能是60 is ),不使用(除了包含主方法的一个类和调用本机库的另一个类之外)。
本机库方法是一个长时间运行的方法,并执行许多错误和释放。分裂是我自己也想到的一种解释。但是,由于没有激活的Java代码,所以对于Java程序和c程序来说,碎片行为应该是相同的。由于它是不同的,我还假设在c程序或Java程序中运行时,使用的malloc实现是不同的。
发布于 2010-01-28 16:11:15
抱歉,各位。错误的假设。
我已经习惯了Sun Java实现用于默认最大堆大小的64 to。但我使用OpenJDK1.6进行测试。如果没有显式指定最大堆大小,Openjdk将使用物理内存的一部分。对我来说是四分之一。我用了一台4GB的机器。因此,四分之一就是1GB。这就是C和Java之间的区别。
可悲的是,这种行为在任何地方都没有被记录下来。我发现它查看openjdk (arguments.cpp)的源代码:
// If the maximum heap size has not been set with -Xmx,
// then set it as fraction of the size of physical memory,
// respecting the maximum and minimum sizes of the heap.发布于 2010-01-20 16:22:32
猜测:在JVM内部运行时,您可能使用的是一个非默认的malloc实现,这符合JVM的特殊需求,并且比常规libc实现中的通用malloc产生更多的开销。
发布于 2010-01-20 16:23:21
Java的堆需要有连续的内存,所以它可以将最大内存大小作为虚拟内存分配。但是,这不会消耗物理内存,甚至可能不会使用交换。我会检查一下你的常驻记忆增加了多少。
https://stackoverflow.com/questions/2102860
复制相似问题