본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Volley 를 이용한 동영상 업로드 테스트 결과.

by 돼지왕 왕돼지 2014. 4. 20.
반응형

 android, Volley 를 이용한 동영상 업로드 테스트 결과.

 

[android] Volley 를 이용한 동영상 업로드 테스트 결과.


테스트 환경


국내 android major 단말들이라고 할 수 있는 Galaxy S 시리즈와 Note 1 을 대상으로 삼았다.

동영상 업로드 방법은 Volley 와 MultipartRequest 를 이용한 일시 업로드이다.







Galaxy S / hdpi / 2.3.4


12.5M 동영상 ( 30초 )


-

process mem = 64MB

runtime maxMemory = 64MB

runtime totalMemory = 5MB

runtime freeMemory = 2MB

native threshold = 26MB

native availMem = 83MB


-

Out of memory on a 26310336-byte allocation.


 java.lang.OutOfMemoryError

  at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)

  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:216)

  at org.apache.harmony.luni.internal.net.www.protocol.http.RetryableOutputStream.write(RetryableOutputStream.java:60)

  at java.io.DataOutputStream.write(DataOutputStream.java:99)

  at java.io.FilterOutputStream.write(FilterOutputStream.java:105)

  at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:244)

  at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:226)

  at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:108)

  at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)

  at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)



-

OOM 을 초래하는 Allocation 된 memory 를 보니, 약 26MB 로 native threshold 와 일치한다.

가용 가능한 native memory 가 83MB 인데, native threshold 가 26MB 인걸로 보아, 가용 native memory 가 높아도 앱에 허용되는 native memory 는 native threshold 로 제한되는 모양이다.



-

동영상 용량이 12.5MB 인데 약 2배의 메모리를 가용하는 것으로 보아,

MultipartRequest 를 작성할 때 Multipart body 에 byte 코드로 1회 로딩하고,

Volley 대부에서 request body 에 다시 한번 이 내용을 쓰는 과정에서 byte 코드를 복사하므로,

2배의 메모리를 사용하는 것으로 보인다.



GALAXY S2 / hdpi / 4.1.2


-

43.25M 동영상 ( 30초 )


-

process mem = 48MB

runtime maxMemory = 128MB

runtime totalMemory = 13MB

runtime freeMemory = 1MB

native threshold = 64MB

native availMem = 243MB


-

Out of memory on a 67101078-byte allocation.

 FATAL EXCEPTION: Thread-1177

 java.lang.OutOfMemoryError

  at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)

  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)

  at org.apache.http.entity.mime.content.FileBody.writeTo(FileBody.java:97)

  at org.apache.http.entity.mime.HttpMultipart.doWriteTo(HttpMultipart.java:206)

  at org.apache.http.entity.mime.HttpMultipart.writeTo(HttpMultipart.java:224)

  at org.apache.http.entity.mime.MultipartEntity.writeTo(MultipartEntity.java:183)

  at com.imcompany.school2.rest.MultipartRequest.getBody(MultipartRequest.java:92)

  at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:239)

  at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:226)

  at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:108)

  at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)

  at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)


-

마찬가지로 native threshold 가 limit 가 되었다.


-

용량이 43.25MB 인걸로 보아

첫번째 multipart body 에 write 는 성공했지만, volley 내부의 request body 에 copy 하던 과정에서 두배인 약 86MB 가 안 되었어도,

threshold 를 넘었기 때문에 OOM 이 발생한 것으로 보인다.






Galaxy S3 / xhdpi / 4.1.2


-

61.0M 동영상 ( 30초 )


-

process mem = 64MB

runtime maxMemory = 256MB

runtime totalMemory = 203MB

runtime freeMemory = 186MB

native threshold = 64MB

native availMem = 781MB


-

no error.


-

Galaxy S3 는 그래도 나름 최신 framework 를 가지고 있어서인지,

똑같은 로직이라면 61MB 동영상을 올리는 과정에서 native threshold 가 64MB 이기 때문에

같은 OOM 을 방출해야 하는데 이를 방출하지 않았다.

왜인지 정말 궁금하지만, 지금 생각할 수 있는 것은 native framework 의 http 관련 library update 로밖에 생각을 못하겠다..

아 궁금해!!




Galaxy Note / xhdpi / 4.0.4

-

43.8M 동영상 ( 30초 )


-

process mem = 64MB

runtime maxMemory = 148MB

runtime totalMemory = 15MB

runtime freeMemory = 0MB

native threshold = 80MB

native availMem = 142MB


-

Out of memory on a 91892526-byte allocation.

 FATAL EXCEPTION: Thread-921

 java.lang.OutOfMemoryError

  at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)

  at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)

  at libcore.net.http.RetryableOutputStream.write(RetryableOutputStream.java:61)

  at java.io.DataOutputStream.write(DataOutputStream.java:98)

  at java.io.OutputStream.write(OutputStream.java:82)

  at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:244)

  at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:226)

  at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:108)

  at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)

  at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)


-
Galaxy S3 와는 다르게 다른 폰들과 같은 증상을 보였다.










해결책


-

해결책은 Volley & Multipart request 를 이용하여 2중으로 memory 를 사용하는 것이 아닌,

기본 HttpClient 와 같은 녀석들을 써서 inputstream 을 이용한 분할 업로딩을 하는 방법이 있겠다.


-

두번째 해결책은 server side 에서 분할 업로드를 추가 지원하는 방식으로,

여러번에 걸쳐서 multipart request 를 호출하며, packet 번호를 함께 전송하는 방식으로 하면 되겠다.


-

stream 전송은 보통 서버에서 기본 지원하는 녀석으로 httpclient 등을 이용해서 stream 전송을 할줄만 안다면 첫번째 방법이 훨씬 general 하며 쉬운 방법이다.






반응형

댓글