dalvikvm-heap 在上传视频时增长堆(碎片案例)android

Posted

技术标签:

【中文标题】dalvikvm-heap 在上传视频时增长堆(碎片案例)android【英文标题】:dalvikvm-heap grow heap (frag case) while upload video android 【发布时间】:2013-03-18 13:41:34 【问题描述】:

我在从 4x 设备上传视频时遇到问题。我知道只有 15 秒的视频录制会在三星 S2 中创建一个 30 mb 的文件,但是当我尝试首先在 php 服务器上上传视频时,它显示喜欢味精 D/dalvikvm(7638):GC_FOR_ALLOC释放263K,9%释放12838K/14087K,暂停13ms,共13ms I/dalvikvm-heap(7638):将堆(碎片情况)增加到 14.481MB,分配 1048592 字节 D/dalvikvm(7638): GC_FOR_ALLOC freed

I know it is the memory managment concept and device memory dependent but I want a real solution for it as I am stuck here from quite a few days.
Below is my code to call and upload the video to server.

public void newmethod( String Imageurl ) throws ClientProtocolException, IOException

    byte[] data ; 
    int bytenumber,bufferSize,bytesRead;
    int maxBufferSize = 1*1024*1024;
      DataOutputStream dos = null;
     //File sourceFile =  searchForFileInExternalStorage("video.3gp");

     Log.e("in the method the path", ""+Imageurl);

      FileInputStream fileInputStream = new FileInputStream(Imageurl);
      bytenumber = fileInputStream.available();
      Log.e("in the method the the size of the file is", ""+bytenumber);
     // dos = new DataOutputStream(conn.getOutputStream());
      bufferSize = Math.min(bytenumber, maxBufferSize);
      data = new byte[bufferSize];
     //ProgressDialog pr = new ProgressDialog(getApplicationContext());
    // pr.addContentView(getCurrentFocus(), null);
       // read file and write it into form...
       bytesRead = fileInputStream.read(data, 0, bufferSize);

       while (bytesRead > 0) 
       // dos.write(data, 0, bufferSize);
        bytenumber = fileInputStream.available();
         bufferSize = Math.min(bytenumber, maxBufferSize);
        bytesRead = fileInputStream.read(data, 0, bufferSize);
        

     // pr.show();


    HttpClient httpClient = new DefaultHttpClient();
    HttpPost postRequest = new HttpPost("http://67.52.165.116/Kakz/mobiles/uploadvideo");
    ByteArrayBody bab = new ByteArrayBody( data, Imageurl);
    MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
    reqEntity.addPart("user_video", bab);

    FormBodyPart bodyPart=new FormBodyPart("title", new StringBody(title));
    reqEntity.addPart(bodyPart);
    bodyPart=new FormBodyPart("desc", new StringBody(description));
    reqEntity.addPart(bodyPart);
    bodyPart=new FormBodyPart("source", new StringBody("android"));
    reqEntity.addPart(bodyPart); 
    postRequest.setEntity(reqEntity);
    final HttpResponse response = httpClient.execute(postRequest);
    // FileInputStream fileInputStream = new FileInputStream(response.getEntity().getContent());


    runOnUiThread(new Runnable() 
         public void run() 

    //stuff that updates ui

             BufferedReader in = null;
            try 
                in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

             catch (IllegalStateException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
             catch (IOException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
            
                String line = null;

    try 
        while((line = in.readLine()) != null) 
            System.out.println(line);

            titleText.setText("");
            descriptionText.setText("");
          //  Toast.makeText(getApplicationContext(), "Video Uploaded successfully", Toast.LENGTH_LONG).show();

            if (line.equalsIgnoreCase("Its too Heavy")) 
            //  pr.dismiss();
                // titleText.setText("");
                //descriptionText.setText("");
                Toast.makeText(getApplicationContext(), "Video size is too heavy", Toast.LENGTH_LONG).show();

            

            else if (line.equalsIgnoreCase("Error")) 
            //  pr.dismiss();
                // titleText.setText("");
                //descriptionText.setText("");
                Toast.makeText(getApplicationContext(), "Error uploading video", Toast.LENGTH_LONG).show();


            

            else  if (line.equalsIgnoreCase("Uploaded")) 
                //pr.dismiss();
                 //titleText.setText("");
                //descriptionText.setText("");
                Toast.makeText(getApplicationContext(), "Video uploaded successfully", Toast.LENGTH_LONG).show();

            

        
     catch (IOException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    
         
);

Please let me know that how I should manage the code to get it right.
Any help would be appreciated ASAP`enter code here`

【问题讨论】:

后台线程上传?? 除非您在相当长的时间内收到垃圾邮件,否则我不会太担心。你正在做一个沉重的动作,它只需要一些记忆。您的应用从一开始就获得了最小的堆大小,并且有针对这些情况的增长空间。 @Raghunandan 是的,我在 asyntask 后台上传它。 @StefandeBruijn 那么有什么办法可以控制这件事,看看我的代码。有时我最多可以上传 20 mb,但有时会上传。 您不想为此使用 AsyncTask。每当您的 Activity 被销毁时,它将被取消。 【参考方案1】:

我在从 4x 设备上传视频时遇到问题。

没问题。当您进行成本非常高的操作时,这是正常行为。您的堆大小(隐式确定)在一瞬间还不够,因此需要长大。你应该如何写入清单是相同的行为

android:largeHeap="true"

此属性不起作用。当堆需要更大的大小时,它会自己长大——当它需要的时候。 当您没有太多内存时,通常会显示此消息。

GC_FOR_ALLOC 释放 263K,9% 释放 12838K/14087K,暂停 13ms,总计 13ms I/dalvikvm-heap(7638)

这里你只有 9% 的内存和堆需要长大。通常它发生在ALLOC 小于 10% 并且是否使用 Thread 无关紧要,一旦它是高成本操作。当您的堆大小达到一个“临界点”时,出于安全原因以及虚拟机,应用程序将自动停止。

一种可能的解决方案是,您需要将文件拆分成更小的块并逐个上传。

【讨论】:

谢谢你的解释你可以看到我已经以多部分的形式发送视频。还有什么我需要将视频分成块的吗?? @vyas 您可以在服务器上发送时以编程方式将文件拆分为更小的块,但在服务器上您应该合并它们,但现在我认为这个想法并不好,因为它是视频。我的意思是,因为它的文件很大,所以没有修复它。它在 logcat 中的唯一警告,如果您的文件上传成功,则仅加载 CPU 和 RAM 没有问题。【参考方案2】:

我不知道回答我自己的问题是个好主意。但是我仍然想为那些像我一样面临同样问题的人提供我的经验,因为在搜索了很多东西后,我知道这个问题没有具体的解决方案,因为它依赖于设备和大量的内存消耗过程。 然后我寻找其他选项,例如在上传之前压缩视频,但我也没有为此获得任何开源库。所以现在视频上传并不像我一开始想的那么简单。 :)

【讨论】:

以上是关于dalvikvm-heap 在上传视频时增长堆(碎片案例)android的主要内容,如果未能解决你的问题,请参考以下文章

停止与核心数据托管对象相关的堆增长

抖音上的视频素材哪里可以找免费的

堆、栈和数据存储单元的大小

C# / .Net Framework 中的堆大小 - 它可以增长吗?如何增长? [复制]

如何在 iOS 中跟踪负责堆增长的代码

如何将图片上传到Cloudinary云平台?