Frequently Asked Questions

Releasing Document instance may take longer

Loading DjVu files of many pages causes serious memory fragmentation and it might results in slowness on delete calls. You can ease the condition to some extent by using Chunk::compact method. The method linearize the memory use of the Chunk instance.
Even with such tricks, if you suffer from severe memory fragmentation, you can use LFH on Windows. For more information, see delete/delete[] calls are too slow on my code .

I've got many linker error when building samples!

Basically, on Linux machine (but it's also true with future OS X machine), we should explicitly specify the compiler to build the codes by CXX variable like the following commandline:

make CXX=g++33

With Visual Studio .NET, my code (I've simply copy-n-pasted the code on the tutorial) causes runtime exception.

Please check your compiler settings, without /GR option, you may happen to get such result. For more information, see Windows Development Notes.

String instance crashes when initialized as a global variable.

In general, global variables are initialized before execution of some initialization codes and also before main(). Since String depends on initialization of some components, it should not be used before them and it could not be a global variable.
Anyway, if it could not be non-global variable, there is a way to make it fake-global variable:

String& getMyFakeGlobalVariable()
{
static String str;
return str;
}

delete/delete[] calls are too slow on my code

On some memory condition, especially on multithreading code, memory allocation/releasing codes cause much fragmentation of memory blocks due to its frequent use of small memory blocks and it makes the delete calls so slow.
On Windows XP or later (and also Windows 2000 with a hotfix), there's a mechanism to improve such situation, named low-fragmentation heap. You can enable this by inserting the following code to your startup routine or code which is executed in relatively earlier stage/phase of your code:

#if _MSC_VER >= 1400
typedef BOOL (WINAPI *fp_HeapSetInfo)(
HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
fp_HeapSetInfo hsi = (fp_HeapSetInfo)GetProcAddress(
GetModuleHandle(_T("Kernel32")), "HeapSetInformation");
if(hsi)
{
ULONG flags = 2;
HANDLE hHeap = (HANDLE)_get_heap_handle();
if(hsi(hHeap, HeapCompatibilityInformation, &flags, sizeof(flags)))
{
// MessageBox(NULL, _T("Wow, LFH is enabled!"), _T("Enabling LFH"), MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL);
}
#endif

There're still several notices for this code:

For further improvement, MemoryAllocator is the last resort; implementing your own allocator to completely isolate SDK's heap. The following code is a sample of custom allocator to use native Windows heap:

class MyIsolatedMemoryAllocator : public Celartem::MemoryAllocator
{
public:
// This is the function which should be called in startup routine of
// your code.
static void init()
{
static MyIsolatedMemoryAllocator me;
}
private:
MyIsolatedMemoryAllocator()
{
m_hHeap = HeapCreate(0, 1024 * 1024, 0); // Initial: 1MB
if(m_hHeap)
{
#if _MSC_VER >= 1400
typedef BOOL (WINAPI *fp_HeapSetInfo)(
HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
fp_HeapSetInfo hsi = (fp_HeapSetInfo)GetProcAddress(
GetModuleHandle(_T("Kernel32")), "HeapSetInformation");
if(hsi)
{
ULONG flags = 2;
if(hsi(m_hHeap, HeapCompatibilityInformation, &flags, sizeof(flags)))
{
// MessageBox(NULL, _T("Wow, LFH is enabled!"), _T("Enabling LFH"), MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL);
}
}
#endif
}
}
~MyIsolatedMemoryAllocator()
{
if(m_hHeap)
HeapDestroy(m_hHeap);
}
virtual CEL_RESTRICT_RETVAL void *allocate(size_t inBlockSize)
{
return HeapAlloc(m_hHeap, 0, inBlockSize);
}
virtual void free(void *inMemoryBlockPtr)
{
HeapFree(m_hHeap, 0, inMemoryBlockPtr);
}
private:
HANDLE m_hHeap;
MyIsolatedMemoryAllocator(const MyIsolatedMemoryAllocator&);
MyIsolatedMemoryAllocator& operator=(const MyIsolatedMemoryAllocator&);
};

Anyway, please don't forget to call MyIsolatedMemoryAllocator::init() on your startup code.

What causes errOutOfMemory exception?

SimpleArray throws exceptions of errOutOfMemory if the underlying MemoryAllocator instance cannot allocate memory due to some situation.
The built-in allocator uses std::malloc to allocate memory and the actual condition depends on the operating system and C/C++ runtime library.
To debug the memory allocation, you can change it by MemoryAllocator::setDefault function but much care should be taken for global/static objects before replacing the allocator.

The following is a sample code to replace the allocator:

class MyMemoryAllocator : public MemoryAllocator
{
public:
MyMemoryAllocator() {}
virtual CEL_RESTRICT_RETVAL void *allocate(size_t inBlockSize)
{
return new unsigned char[inBlockSize];
}
virtual void free(void *inMemoryBlockPtr)
{
delete[] static_cast<unsigned char*>(inMemoryBlockPtr);
}
};
MyMemoryAllocator global_myAllocatorInstance;
...
// replace the built-in allocator.
// be aware that SimpleArray instances are allocated before this.
MemoryAllocator::setDefault(&global_myAllocatorInstance);

For more realistic MemoryAllocator sample, see delete/delete[] calls are too slow on my code.


Cuminas DjVu SDK 3.0.33103
This document is made with doxygen 1.8.5 at Sun Dec 15 2013 19:38:06.
Cuminas Logo