Android中的内存泄漏

Android中的内存泄漏,android,Android,我有一个与内存泄漏有关的问题。在我的应用程序中,我必须从视频文件中读取2MB数据,当活动的onCreate方法调用代码中分配2MB字节数组的同一语句时,总是调用与该方法相关的方法,因为堆内存超过了内存,所以在10到15次尝试后,经常返回OutofMemory异常。代码解释如下(它是我整个代码的一部分): //从SD卡读取DRM视频 File File=新文件(“/sdcard/TvAnyTime/watch/”+IDValue+”.mp4”); 试一试{ is=新文件输入流(文件); }捕获(F

我有一个与内存泄漏有关的问题。在我的应用程序中,我必须从视频文件中读取2MB数据,当活动的onCreate方法调用代码中分配2MB字节数组的同一语句时,总是调用与该方法相关的方法,因为堆内存超过了内存,所以在10到15次尝试后,经常返回OutofMemory异常。代码解释如下(它是我整个代码的一部分):

//从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数据。请参阅我的编辑。你不想看整个文件,对吗?是的,汉诺,非常感谢你这样回答..我认为这是正确的方法,肯定会奏效的…再次感谢。