Hi all,
The past few queries i wanted to convey this ,,.
Please tell me if u get some solution for this ....
Description :-
I am facing memory leak problem in the following JNI
calls.
FindClass ()
CallStaticObjectMethod ()
CallIntMethod ()
GetStaticMethodID ()
GetMethodID ()
JNI_CreateJavaVM ()
When i use the above mentioned JNI calls in my code then
memory leak occurrs and the memory consumption increases
continiously.
Below is the sample code that i used to confirm the memory
leak in the JNI calls.
#include <jni.h>
#include <windows.h>
#include <conio.h>
#define MAXPATH 1024
#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment"
#define JVM_DLL "jvm.dll"
#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif
#define USER_CLASSPATH "." /* where Prog.class is */
typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args);
typedef struct {
CreateJavaVM_t CreateJavaVM;
GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs;
} InvocationFunctions;
jboolean
LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
{
HINSTANCE handle;
/* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) {
fprintf(stderr, "Error loading: %s\n", jvmpath);
return JNI_FALSE;
}
/* Now get the function addresses */
ifn->CreateJavaVM =
(CreateJavaVM_t)GetProcAddress(handle, "JNI_CreateJavaVM");
ifn->GetDefaultJavaVMInitArgs =
(GetDefaultJavaVMInitArgs_t)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) {
fprintf(stderr, "Error: can't find JNI interfaces in: %s\n", jvmpath);
return JNI_FALSE;
}
return JNI_TRUE;
}
static jboolean
GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize)
{
DWORD type, size;
if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0
&& type == REG_SZ
&& (size < (unsigned int)bufsize)) {
if (RegQueryValueEx(key, name, 0, 0, (LPBYTE)buf, &size) == 0) {
return JNI_TRUE;
}
}
return JNI_FALSE;
}
static jboolean
GetPublicJREHome(char *buf, jint bufsize)
{
HKEY key, subkey;
char version[MAXPATH];
/* Find the current version of the JRE */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) {
fprintf(stderr, "Error opening registry key '" JRE_KEY "'\n");
return JNI_FALSE;
}
if (!GetStringFromRegistry(key, "CurrentVersion",
version, sizeof(version))) {
fprintf(stderr, "Failed reading value of registry key:\n\t"
JRE_KEY "\\CurrentVersion\n");
RegCloseKey(key);
return JNI_FALSE;
}
/* Find directory where the current version is installed. */
if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) {
fprintf(stderr, "Error opening registry key '"
JRE_KEY "\\%s'\n", version);
RegCloseKey(key);
return JNI_FALSE;
}
if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) {
fprintf(stderr, "Failed reading value of registry key:\n\t"
JRE_KEY "\\%s\\JavaHome\n", version);
RegCloseKey(key);
RegCloseKey(subkey);
return JNI_FALSE;
}
RegCloseKey(key);
RegCloseKey(subkey);
return JNI_TRUE;
}
main() {
InvocationFunctions ifn;
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs args;
JavaVMOption options[1];
jint res;
jobject obj;
jclass cls;
jmethodID mid;
char jvmpath[MAXPATH];
/* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
GetPublicJREHome(jvmpath,MAXPATH);
strcat(jvmpath,"\\bin\\client\\jvm.dll");
ifn.CreateJavaVM = 0; ifn.GetDefaultJavaVMInitArgs = 0;
LoadJavaVM(jvmpath, &ifn);
// Fill the args structure
args.version = JNI_VERSION_1_4;
args.nOptions = 1;
options[0].optionString = "-Djava.class.path=E:\\sample";
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
// Create the Java VM
//res = JNI_CreateJavaVM(&jvm,(void **)&env,&args);
res = (*ifn.CreateJavaVM)(&jvm,(void **)&env,&args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
}
// Find the User defined class
cls = env->FindClass("HelloWorld");
if (cls == 0) {
res=GetLastError();
fprintf(stderr, "Can't find Hello World class\n");
exit(1);
}
int i=0;
while(1)
{
// Get the Method Id to be invoked
mid = env->GetMethodID(cls, "sample", "()V");
if (mid == 0) {
return 1;
}
// Creation of New Object and Execution of Method
obj = env->NewObject(cls,mid);
i++;
// Calling the Method using the object
env->CallVoidMethod(obj, mid);
//mid =NULL;
// Get the static method ID
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if (mid == 0) {
fprintf(stderr, "Can't find Prog.main\n");
exit(1);
}
// Invoking the main function call
env->CallStaticVoidMethod(cls, mid);
//mid =NULL;
// Creation of new object
jobject obj1 = env->AllocObject(cls);
// Get the Method Id to be invoked
mid = env->GetMethodID(cls,"sum","(II)I");
jint result;
// Invoking the method using parameters
//while(i<=500)
//{
result = env->CallIntMethod(obj1,mid,2,6);
i++;
//}
//mid =NULL;
printf("\nResult is %d",result);
// Invoking the Constructor
mid = env->GetMethodID(cls,"<init>","(I)V");
env->CallVoidMethod(obj1,mid,4);
//mid =NULL;
mid = env->GetMethodID(cls,"getVar","()I");
jint r2 = env->CallIntMethod(obj1,mid);
//mid =NULL;
// Deletion of objects
env->DeleteLocalRef(obj);
env->DeleteLocalRef(obj1);
}
jvm->DestroyJavaVM();
getch();
}
thanks & regards,
Ootsoo