这是我的情况:我手头的任务需要大量的记忆.我没有足够的RAM,不管我试过什么(Jrockit / 3gb开关等),我不能给JVM足够的ram,并且操作被异常终止,告诉我需要更多的堆空间.
有没有办法强制JVM使用操作系统的交换机制,以免内存不足?这是Windows xp 32位
这将需要年龄,但我不在乎,我只需要这个操作即可完成.
我已经用完了选项,我无法控制任何变量.
这是一个必需的编辑,因为我从几乎所有人都得到相同的回应:)
这不是我的代码.有人写了一个工具,将xml文件读入存储库.该工具使用EMF,并一次加载整个模型.我所能做的就是将它提供给XML文件.
在Windows或Linux等运行本机代码的情况下,操作系统会使用虚拟内存/交换空间为其提供内存,并且应用程序不了解它.
我想知道是否可以对JVM做同样的事情.在Windows 32位下,-Xmx可以达到一定的数量,但这还不够.
出门购买新硬件目前不是我的选择.所以我想知道是否可以使JVM像本地进程一样工作.慢,但仍在工作.
显然这是不可能的,我没有运气.我只需要知道我是否真的出于选择.
解决方法
显然,Java堆的限制有一个方法.它甚至用于名为
BigMemory的商业产品,它基本上允许您通过透明地交换到OS交换和/或磁盘(如果需要)具有几乎无限的内存.
这个想法是使用直接的ByteBuffers来存储你的对象数据.因为直接字节缓冲区的内容存储在本地进程内存(而不是堆)中,您可以依靠操作系统交换机制为您交换内存.我在this website发现了这个(在页面上搜索’直接字节缓冲区’).
这是你如何实现它(java-pseudo-code’ish):
class NativeMemoryCache{ private Map<Object,ByteBuffer> data = new HashMap<...>(); public void put(Object key,Serializable object){ byte[] bytes = serialize(object); //allocate native memory to store our object ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length); buf.put(bytes); buf.flip(); data.put(key,buf); } public Object get(Object key){ ByteBuffer buf = data.get(key).duplicate(); byte[] bytes = new byte[buf.remaining()]; buf.get(bytes); return deserialize(bytes); } private byte[] serialize(Object obj){ ... } private Object deserialize(byte[] bytes){ ... } }
希望你能得到这个想法.你只需要实现序列化(你也可以使用zip压缩你的对象,如果你有很少的大对象,特别是包含可拉链数据,如字符串),这将是有效的.
当然NativeMemoryCache对象,数据哈希映射和密钥将在堆中,但这不应该占用很多内存.