64位Windows 10上的Java 32位内存阈值

时间:2017-11-16 23:16:42

标签: java performance memory memory-management out-of-memory

我有一些软件需要大约1500米的内存才能正常运行。我使用xms和xmx在开始时强制使用此数量,以确保它具有所需的内存。我曾经在Windows XP或Windows 7上运行它,运行正常。切换到Windows 10后,我突然发现我没有足够的内存来运行它。在研究了Java中的内存如何工作之后,我在这个页面上看到了以下信息:

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit

  

由于各种附加约束,例如可用交换,内核地址空间使用,内存碎片和VM开销,实际上限制可以低得多。在大多数现代32位Windows系统上,最大堆大小范围为1.4G到1.6G。

听起来我已经在32位Java能力的边缘运行了。测试我的机器的极限似乎我当前的最大值约为1.1克。目前切换到64位可能不在桌面上,所以我试图弄清楚如何从我的最大内存阈值中丢失大约.5g。我已经尝试过研究FAQ中列出的所有可能影响它的事情。

  • 可用交换:这似乎是页面文件或虚拟内存。显然增加这一点有时会有所帮助。有时当我增加它时,我会看到重启后暂时的改进,但如果我再次重新启动,修复似乎永远不会持续。

  • 内核地址空间使用情况:这似乎是操作系统的内存上限。我们无法改变这一点吗?

  • 内存碎片:据说Windows 10实际上比以前版本的Windows更好地处理它。所以这不应该是一个因素。

  • 虚拟机开销:似乎它指的是其他虚拟机的RAM使用情况。除了Java之外我不认为我还有其他任何可以运行的虚拟机。

是否有任何可靠的方法来识别和纠正可能导致Windows版本之间性能差异的原因?它非常令人沮丧,因为我现在拥有的物理内存比以往任何时候都多,但唯一重要的RAM是允许使用RAM JVM,现在它已经不多了。

更新

我听到了你的声音。我知道我可以轻松修复它切换到64位;我的问题是如何在不这样做的情况下解决问题。理解JVM如何根据学术原因以及实际来确定它的最大堆量是否有帮助?我怀疑有很多应用程序达到了64位Java的上限,但如果存在Java,那么Java的行为方式是否相同?

1 个答案:

答案 0 :(得分:3)

我无法弄清楚为什么系统之间的内存不同,但我确实知道了我可以在Java.exe上设置的LARGEADDRESSAWARE标志,它允许它拥有高达1G的内存更多的记忆。

在人们通常用于设置标志的几个工具中,我发现这个自定义编码的python脚本试图在你提交的任何.exe文件上设置它。使用它我能够将它提供给Java.exe,现在一切正常。

通常不建议设置此标志,但到目前为止没有副作用。我将使用它,直到我可以正确地将所有内容切换到64位。

https://github.com/pyinstaller/pyinstaller/issues/1288

# See http://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files#PE_Header
# and https://msdn.microsoft.com/en-us/library/ms680349%28v=vs.85%29.aspx

import struct

IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020
PE_HEADER_OFFSET = 60
CHARACTERISTICS_OFFSET = 18

def set_large_address_aware(filename):
    f = open(filename, 'rb+')
    # Check for MZ Header
    if f.read(2) != b'MZ':
        print('Not MZ')
        return False
    # Get PE header location
    f.seek(PE_HEADER_OFFSET)
    pe_header_loc, = struct.unpack('i', f.read(4))
    # Get PE header, check it
    f.seek(pe_header_loc)
    if f.read(4) != b'PE\0\0':
        print('error in PE header')
        return False
    # Get Characteristics, check if IMAGE_FILE_LARGE_ADDRESS_AWARE bit is set
    charac_offset = pe_header_loc + 4 + CHARACTERISTICS_OFFSET
    f.seek(charac_offset)
    bits, = struct.unpack('h', f.read(2))
    if (bits & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE:
        return True
    else:
        print('large_address_aware is NOT set - will try to set')
        f.seek(charac_offset)
        bytes = struct.pack('h', (bits | IMAGE_FILE_LARGE_ADDRESS_AWARE))
        f.write(bytes)
    f.close()
    return False

if set_large_address_aware('file.exe'):
    print('large_address_aware is set')
else:
    print('large_address_aware was NOT set')