jnienv - Return a big object array from JNI? -
according doc
jint ensurelocalcapacity(jnienv *env, jint capacity);
ensures @ least given number of local references can created in current thread. returns 0 on success; otherwise returns negative number , throws outofmemoryerror.
before enters native method, vm automatically ensures @ least 16 local references can created.
for backward compatibility, vm allocates local references beyond ensured capacity. (as debugging support, vm may give user warnings many local references being created. in jdk, programmer can supply -verbose:jni command line option turn on these messages.) vm calls fatalerror if no more local references can created beyond ensured capacity.
it seems there limitation number of local reference can created.
and have following code return big object array, leads lot of local reference creation. mean reach limitation easily? -- doc says 16 default.
extern "c" jniexport jobjectarray jnicall java_messagequeueinterop_receive(jnienv * env, jobject this_obj, jclass cls) { int count = 99999; jobjectarray ret = env->newobjectarray( count, cls, null); if( ret ){ for( int = 0; < count; i++ ) { jobject obj = env->newobject( cls, constructor); if( obj ){ env->setintfield( obj, fieldid1, 2); jstring str = env->newstringutf("xxx"); if( str ) env->setobjectfield( obj, fieldid2, str); env->setobjectarrayelement( ret, i, obj); } } } return ret; }
how extend limitation?
well 100,000 > 16 have trouble.
you try combination of pushlocalframe()
, poplocalframe()
, follows:
extern "c" jniexport jobjectarray jnicall java_messagequeueinterop_receive(jnienv * env, jobject this_obj, jclass cls) { int count = 99999; jobjectarray ret = env->newobjectarray( count, cls, null); if( ret ){ for( int = 0; < count; i++ ) { pushlocalframe(env, 1); // todo error checking required here jobject obj = env->newobject( cls, constructor); if( obj ){ env->setintfield( obj, fieldid1, 2); jstring str = env->newstringutf("xxx"); if( str ) env->setobjectfield( obj, fieldid2, str); } obj = poplocalframe(env, obj); env->setobjectarrayelement( ret, i, obj); } } return ret; }
e&oe. might work, might not. [on second thoughts, not.]
it might better have caller provide linkedlist
don't have allocate huge array, , maybe calling loop add 1 element native queue @ time inside jni, or else callback java allocate object.
Comments
Post a Comment