Cocos中调用JNI,报错local reference table overflow (max=512)
2017-12-15 01:19
162 查看
最近公司的游戏项目中出现了一个奇怪的bug。安卓端当旁观玩家过多,比如达到150人的时候,直接崩溃。
出现这个bug的时候,我也很崩溃。仔细看了一下log,提示
百度一下,说是Android JNI局部引用表溢出。
根据操作步骤,定位到了lua代码中的引起报错的代码块。仔细查看了代码,发现是lua调用android端方法,获取旁观者的昵称与备注。因为lua调用android端方法是通过
这样一来,思路很清晰了,根据网上教程,字符串使用完成之后,调用DeleteLocalRef删除局部引用。一看到这很激动,马上就能解决问题了。然后返回到实际C++代码中一看,发现并没有网上说的创建新的字符串的情况,死马当活马医医,依葫芦画瓢一下。改好C++之后,重新编译so文件,测试一下,然并卵,该崩溃照样崩溃。
后来再仔细看了一下lua代码,发现代码中根据旁观者人数集合长度,循环的在调用JNI。转变思路一想,我把集合直接传给android端,android端查找好昵称之后,再传回给lua,这样JNI只需要调用一次了。按照思路修改了之后,果然可以了。
其实还有更好的解决方案:本局游戏中进入了玩家之后,服务端发送进入通知,带上所有玩家的信息,缓存好所有玩家信息,这样需要显示时,只需要查找缓存,不需要从app端调用方法查询。这样省时省力省内存。
修改bug主要是思路上要清晰。虽然看起来我这写的很简单,但是其中走了很多弯路。定位问题不够准确,导致浪费了很多时间。以后要注意
出现这个bug的时候,我也很崩溃。仔细看了一下log,提示
`local reference table overflow (max=512)`
百度一下,说是Android JNI局部引用表溢出。
根据操作步骤,定位到了lua代码中的引起报错的代码块。仔细查看了代码,发现是lua调用android端方法,获取旁观者的昵称与备注。因为lua调用android端方法是通过
luaj.callStaticMethod去调用,再捋一下实现方法,发现是在lua-bindings的CCC代码中去实现。好,按照网上的说法,是因为循环创建新的字符串并返回指向这个字符串的局部引用,这样造成局部引用表被填满。而Android中局部引用表默认最大容量是512个。
这样一来,思路很清晰了,根据网上教程,字符串使用完成之后,调用DeleteLocalRef删除局部引用。一看到这很激动,马上就能解决问题了。然后返回到实际C++代码中一看,发现并没有网上说的创建新的字符串的情况,死马当活马医医,依葫芦画瓢一下。改好C++之后,重新编译so文件,测试一下,然并卵,该崩溃照样崩溃。
后来再仔细看了一下lua代码,发现代码中根据旁观者人数集合长度,循环的在调用JNI。转变思路一想,我把集合直接传给android端,android端查找好昵称之后,再传回给lua,这样JNI只需要调用一次了。按照思路修改了之后,果然可以了。
其实还有更好的解决方案:本局游戏中进入了玩家之后,服务端发送进入通知,带上所有玩家的信息,缓存好所有玩家信息,这样需要显示时,只需要查找缓存,不需要从app端调用方法查询。这样省时省力省内存。
修改bug主要是思路上要清晰。虽然看起来我这写的很简单,但是其中走了很多弯路。定位问题不够准确,导致浪费了很多时间。以后要注意
相关文章推荐
- cocos JniHelper调用java时总是报 Failed to find static method id of
- 简单的使用jni调用java方法
- 在java中调用c/c++代码的方法(jni)
- java通过JNI调用C++(VC++6.0) 实例
- JNI调用过程
- jni调用
- windows和linux环境下java调用C++代码-JNI技术
- 简单的使用jni调用java方法
- Android JNI调用(三)
- UNITY调用安桌方法出现 JNI: Init'd AndroidJavaClass with null ptr!
- JNI注册调用源码分析完整过程-安卓4.4
- 通过JNI实现Java和C++的相互调用(转)
- JNI调用机制与JNI实现
- 编写android程序调用jni本地方法的实现
- JNI:java调用c++程序的最常用方法
- android jni中C++与java互相调用小结
- JNI的调用与编写
- 【JNI好学易用系列】之三:JNI方法调用
- Android JNI调用 - char*与jstring相互转换
- JNI: JAVA通过JNI调用另一个JAVA类的方法