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的主要内容,如果未能解决你的问题,请参考以下文章