首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >操纵256x256位图破坏android的JNI

操纵256x256位图破坏android的JNI
EN

Stack Overflow用户
提问于 2010-11-12 16:43:00
回答 2查看 1.4K关注 0票数 1

也许我在尝试做一些我不该做的事。

我正在模拟器中运行一段代码。它看起来(或多或少)像这样:http://pastie.org/1291380

这是建造一个活壁纸背景。我传入一个位图、调色板和我的位图的array.The大小是256x256。getRedPal / getGreenPal / getBluePal实际上调用了Color.red() / Color.green() / Color.blue(),以便获取调色板对象的rgb颜色组件。

循环缓慢前进;在仿真器崩溃和燃烧之前,我一直到drawInC的j值达到32的地步:

11-11 15:34:44.032: INFO/失真_bmp(598):DrawInC: i: 0 j: 32

11-11 15:34:44.032: INFO/失真_bmp(598)::i: 0 j: 0

11-11 15:34:44.032: INFO/失真_bmp(598)::i: 0 j: 1

11-11 15:34:44.032: INFO/失真_bmp(598)::i: 0 j: 2

11-11 15:34:44.032: INFO/失真_bmp(598)::i: 0 j: 3

11-11 15:34:44.032: INFO/失真_bmp(598)::i: 0 j: 4

之后,我将一个转储文件发送到/data/tombstone。这里是转储(但我真诚地发现其中没有任何价值,只是一堆内存地址):http://pastie.org/1291394

在其他地方读到可以解决问题的文章后,我在标签上添加了android:vmSafeMode="true“。这是在2.2上,使用bitmap.h。

就我个人而言,我对此表示怀疑。

代码语言:javascript
运行
复制
jbyte* buffer = 
(*env)->GetByteArrayElements(env, arr, &isCopy)

调用;我在某个地方从网络中提取了该代码,因为我完全无法从字节数组“arr”中获取值。

有什么想法吗?

编辑后,操作循环迭代器(我缩短了循环的数量),我现在得到一个信息错误:

"ReferenceTable溢出(max=512)“

代码语言:javascript
运行
复制
JNI local reference table summary (512 entries):
  509 of Ljava/lang/Class; 164B (3 unique)
2 of Ljava/lang/String; 28B (2 unique)
   1 of [Ljava/lang/String; 28B
Memory held directly by tracked refs is 576 bytes
Failed adding to JNI local ref table (has 512 entries)

"509 of java.lang.class“在me...how看来不太正确,我可以在这里优化我的代码吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-11-12 22:14:10

从该错误消息中可以看出,一些本地代码调用了返回Class对象的函数,并且已经调用了509次。这些电话中有507次返回了一个特定类别。

JNI本地引用让GC知道本机代码正在查看对象,因此即使在其他地方没有对对象的引用,也无法收集该对象。当本机代码返回到VM时,将释放这些本地推荐程序。如果本机代码在不返回的情况下做了大量工作,则有可能使本地参考表溢出。

您可能只需要在某个地方添加一个DeleteLocalRef。我猜您需要在DrawTile的末尾添加一个,因为GetObjectClass调用。更好的是,将这些GetMethodID调用移动到一个一次性设置函数中。(他们进行字符串搜索来查找方法,这使得它们不是特别快。)

有关更多信息,请参见JNI提示

票数 1
EN

Stack Overflow用户

发布于 2012-04-20 14:19:06

我觉得这可能是记忆问题。你会释放数组吗?

如果您得到的数组

代码语言:javascript
运行
复制
(*env)->GetByteArrayElements(env, arr, &isCopy)

在每个过程之后,您必须在c端释放数组,否则会填满内存,直到超出限制(限制大小取决于android版本和/或制造商,但据我所知,每个应用程序最多为48 my )。

代码语言:javascript
运行
复制
(*env)->ReleaseByteArrayElements(env, arr, &isCopy, 0);

见此处:http://www.iam.ubc.ca/guides/javatut99/native1.1/implementing/array.html

顺便说一句,这个方法确实将数组从java复制到c ++中的一个新内存块,然后在那里工作,最后将其复制回java (在此之前,内存可能已经移动到另一个位置)。为了提高性能,您可以查看https://groups.google.com/forum/?fromgroups#!msg/android-ndk/phDP5zqiYY4/BFMw4zTme8IJ

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4166961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档