僅供參考 - 我發現下面的非常有用的文章:https://forums.oracle.com/forums/thread.jspa?messageID=6463655
我要在這裏重複一些瘋狂有用的代碼,因爲我不知道,我相信甲骨文保持上述論壇圍繞。
當我設置我的JVM時,我使用調用getMaxHeapAvailable(),然後相應地設置我的堆空間(-Xmxm) - 適用於RAM較少的工作站,而不必懲罰具有大量RAM的用戶。
bool canAllocate(DWORD bytes)
{
LPVOID lpvBase;
lpvBase = VirtualAlloc(NULL, bytes, MEM_RESERVE, PAGE_READWRITE);
if (lpvBase == NULL) return false;
VirtualFree(lpvBase, 0, MEM_RELEASE);
return true;
}
int getMaxHeapAvailable(int permGenMB, int maxHeapMB)
{
DWORD originalMaxHeapBytes = 0;
DWORD maxHeapBytes = 0;
int numMemChunks = 0;
SYSTEM_INFO sSysInfo;
DWORD maxPermBytes = permGenMB * NUM_BYTES_PER_MB; // Perm space is in addition to the heap size
DWORD numBytesNeeded = 0;
GetSystemInfo(&sSysInfo);
// jvm aligns as follows:
// quoted from size_t GenCollectorPolicy::compute_max_alignment() of jdk 7 hotspot code:
// The card marking array and the offset arrays for old generations are
// committed in os pages as well. Make sure they are entirely full (to
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
// byte entry and the os page size is 4096, the maximum heap size should
// be 512*4096 = 2MB aligned.
// card_size computation from CardTableModRefBS::SomePublicConstants of jdk 7 hotspot code
int card_shift = 9;
int card_size = 1 << card_shift;
DWORD alignmentBytes = sSysInfo.dwPageSize * card_size;
maxHeapBytes = maxHeapMB * NUM_BYTES_PER_MB;
// make it fit in the alignment structure
maxHeapBytes = maxHeapBytes + (maxHeapBytes % alignmentBytes);
numMemChunks = maxHeapBytes/alignmentBytes;
originalMaxHeapBytes = maxHeapBytes;
// loop and decrement requested amount by one chunk
// until the available amount is found
numBytesNeeded = maxHeapBytes + maxPermBytes;
while (!canAllocate(numBytesNeeded + 50*NUM_BYTES_PER_MB) && numMemChunks > 0) // 50 is an overhead fudge factory per https://forums.oracle.com/forums/thread.jspa?messageID=6463655 (they had 28, I'm bumping it 'just in case')
{
numMemChunks --;
maxHeapBytes = numMemChunks * alignmentBytes;
numBytesNeeded = maxHeapBytes + maxPermBytes;
}
if (numMemChunks == 0) return 0;
// we can allocate the requested size, return it now
if (maxHeapBytes == originalMaxHeapBytes) return maxHeapMB;
// calculate the new MaxHeapSize in megabytes
return maxHeapBytes/NUM_BYTES_PER_MB;
}
您是否將任何選項傳遞給JVM以設置最大堆和/或最大燙髮大小?這兩種尺寸的總和需要作爲JVM啓動的連續塊使用。 – kschneid 2010-08-04 03:00:14
最初,我們只是使用默認值(只是傳遞一個類路徑)。我嘗試傳遞-Xmx和-Xms的各種值。高達52米,dll調用只是導致VB退出(沒有錯誤消息)。從53米起,我得到了JNI_ENOMEM返回碼。當然有足夠的內存可用,除非VB爲dll的內存分配做了一些非常奇怪的事情,那麼應該有足夠的連續內存用於具有53MB堆的JVM。而這一切在我的舊開發盒(以及我們使用過的所有其他機器上)上都可以正常工作。 – 2010-08-04 10:40:29