Android中的内存泄漏
我有一个与内存泄漏有关的问题。在我的应用程序中,我必须从视频文件中读取2MB数据,当活动的onCreate方法调用代码中分配2MB字节数组的同一语句时,总是调用与该方法相关的方法,因为堆内存超过了内存,所以在10到15次尝试后,经常返回OutofMemory异常。代码解释如下(它是我整个代码的一部分):Android中的内存泄漏,android,Android,我有一个与内存泄漏有关的问题。在我的应用程序中,我必须从视频文件中读取2MB数据,当活动的onCreate方法调用代码中分配2MB字节数组的同一语句时,总是调用与该方法相关的方法,因为堆内存超过了内存,所以在10到15次尝试后,经常返回OutofMemory异常。代码解释如下(它是我整个代码的一部分): //从SD卡读取DRM视频 File File=新文件(“/sdcard/TvAnyTime/watch/”+IDValue+”.mp4”); 试一试{ is=新文件输入流(文件); }捕获(F
//从SD卡读取DRM视频
File File=新文件(“/sdcard/TvAnyTime/watch/”+IDValue+”.mp4”);
试一试{
is=新文件输入流(文件);
}捕获(FileNotFoundException e2){
e2.printStackTrace();
}
//读取2^21字节
fileData=新字节[2097152];
int read=0;
while(读取!=fileData.length){
试一试{
read+=is.read(fileData,read,fileData.length-read);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
//最后一个模式在视频文件中被异或2^10次
对于(int i=0;i您可以将fileData作为一个静态指针,然后在caseonCreate中只分配一次内存,当fileData==NULL时;您可以将fileData作为一个静态指针,然后在caseonCreate中只分配一次内存,当fileData==NULL时;您是否考虑过在读取字节的循环中处理输入,而不是读取所有字节
fileData = new byte[2048];
int read = 0;
while(read != fileData.length) {
try {
read += is.read(fileData, read, fileData.length);
for(int i = 0; i < 2048; i++) {
// Processing here
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
fileData=新字节[2048];
int read=0;
while(读取!=fileData.length){
试一试{
read+=is.read(fileData,read,fileData.length);
对于(int i=0;i<2048;i++){
//在这里处理
}
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
您是否考虑过在读取字节的循环中处理输入,而不是读取所有字节
fileData = new byte[2048];
int read = 0;
while(read != fileData.length) {
try {
read += is.read(fileData, read, fileData.length);
for(int i = 0; i < 2048; i++) {
// Processing here
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
fileData=新字节[2048];
int read=0;
while(读取!=fileData.length){
试一试{
read+=is.read(fileData,read,fileData.length);
对于(int i=0;i<2048;i++){
//在这里处理
}
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
您可以将这一关键文件处理从Java代码排除到本机代码。
您可以将这一关键文件处理从Java代码排除到本机代码。
好的,因为我对Kingamajick答案的编辑“神秘地”在等待同行评审时消失了,下面是如何正确地进行文件(或一般的流)分块阅读:
fileData = new byte[2048];
try {
int c = 0;
while( (c = is.read(fileData)) >= 0 ) {
// Process all bytes from fileData[0] through fileData[c-1], e.g.:
for(int i = 0; i < c; i++) {
// do something with fileData[i]
// ...
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
在逐字节处理文件时,正如您在代码摘录中所做的那样,您基本上可以自由选择fileData
缓冲区的大小。较小的缓冲区不会带来任何实际好处,因为它可能会导致底层文件系统上执行更多的读取操作。1kb到64kb的大小通常是合适的。Ok,因为我对Kingamajick答案的编辑“神秘地”在等待同行评审时消失了,下面是如何正确地进行文件(或流)分块阅读:
fileData = new byte[2048];
try {
int c = 0;
while( (c = is.read(fileData)) >= 0 ) {
// Process all bytes from fileData[0] through fileData[c-1], e.g.:
for(int i = 0; i < c; i++) {
// do something with fileData[i]
// ...
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
在逐字节处理文件时,正如您在代码摘录中所做的那样,您基本上可以自由选择fileData
缓冲区的大小。较小的缓冲区不会带来任何实际好处,因为它可能会导致底层文件系统上执行更多的读取操作。1kb到64kb的大小通常是一个不错的大小。你观看并阅读了吗?实际上我的办公室无法访问youtube。请尝试https://而不是http://;)如果他们通过URL阻止了网站,那么这应该可以。如果他们通过IP阻止了网站,那么对不起,我的朋友。网站中的视频可以工作吗?byte[]res=new byte[2048];bytesafterXor=new byte[2048];绝对应该被移出循环!-而read+=is。read(…)也是一个坏主意,因为read()在到达文件末尾时将返回-1。我应该使用read+=而不是read();你看过并阅读了吗?实际上我的办公室无法访问youtube。请尝试https://而不是http://;)如果他们通过URL阻止了该网站,那么这应该是可行的。如果他们通过IP阻止了它,那么对不起我的朋友。网站中的视频正常吗?字节[]res=新字节[2048];bytesafterXor=新字节[2048];绝对应该移到循环之外!-read+=is.read(…)也是个坏主意,因为read()在到达文件末尾时将返回-1;第二种解决方案是在桌面上释放内存并在启动时分配内存,而不是onCreate。请参阅android应用程序生命周期:第二种解决方案是在桌面上释放内存,并在启动时释放所有内存,而不是onCreate。查看android应用程序生命周期:感谢Hanno的回复,但您每次只读取2048位,这不是必需的,并且没有持续增加到2097152,因此我无法使用此代码,因为我必须从文件中读取2MB数据。请查看我的编辑。您不想读取整个文件,是吗?是的,汉诺,非常感谢你这样回答。我认为这是正确的方法,肯定会起作用…再次感谢。感谢汉诺的回答,但你每次只读取2048位,这不是必需的,并且没有持续增加到2097152,因此我不能使用此代码,因为我有从文件中读取2MB数据。请参阅我的编辑。你不想看整个文件,对吗?是的,汉诺,非常感谢你这样回答..我认为这是正确的方法,肯定会奏效的…再次感谢。