我有一些软件需要大约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的行为方式是否相同?
答案 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')