software-mansion / react-native-svg

SVG library for React Native, React Native Web, and plain React web projects.
MIT License
7.44k stars 1.12k forks source link

Out of Memory exception in android #926

Closed praveens96 closed 5 years ago

praveens96 commented 5 years ago

getting the below exception when trying to do a swipe and load some more data in to the svg

E/AndroidRuntime: FATAL EXCEPTION: java.lang.OutOfMemoryError at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:1047) at android.graphics.Bitmap.createBitmap(Bitmap.java:1001) at android.graphics.Bitmap.createBitmap(Bitmap.java:951) at android.graphics.Bitmap.createBitmap(Bitmap.java:912) at com.horcrux.svg.SvgView.drawOutput(SvgView.java:227) at com.horcrux.svg.SvgView.onDraw(SvgView.java:89) at android.view.View.draw(View.java:19453) at android.view.View.draw(View.java:19323) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at android.view.View.draw(View.java:19456) at android.widget.HorizontalScrollView.draw(HorizontalScrollView.java:1663) at com.facebook.react.views.scroll.ReactHorizontalScrollView.draw(ReactHorizontalScrollView.java:415) at android.view.View.draw(View.java:19323) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:699) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:699) at android.view.View.draw(View.java:19456) at android.view.View.draw(View.java:19323) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:699) at android.view.View.draw(View.java:19456) at android.view.View.draw(View.java:19323) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:699) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.views.view.ReactViewGroup.dispatchDraw(ReactViewGroup.java:699) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at com.facebook.react.ReactRootView.dispatchDraw(ReactRootView.java:226) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at android.view.View.draw(View.java:19321) at android.view.ViewGroup.drawChild(ViewGroup.java:4324) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4087) at android.view.View.draw(View.java:19456) at com.android.internal.policy.DecorView.draw(DecorView.java:857) at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:3497) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3411) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3163) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2673) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1612) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7371) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:915) at android.view.Choreographer.doCallbacks(Choreographer.java:727) at android.view.Choreographer.doFrame(Choreographer.java:662) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:901) at android.os.Handler.handleCallback(Handler.java:790) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:197) at android.app.ActivityThread.main(ActivityThread.java:7022) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:515) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:837)

I have a bar graph with timeline, on swipe i am adding some more bars(Rects). after approx. 52 Rects app is crashing with the above exception. tried profiling in android studio. approx. after storage reaches 250 MB app is getting crashed. React Native Info: react-native-cli: 2.0.1 react-native-svg: latest version

how to manage to load more data in react native svg? Any help would be highly appreciated.

on a separate note, here is what i am facing issue with

msand commented 5 years ago

What width and height values do you give your Svg element? I suspect it might be too big to fit in memory.

praveens96 commented 5 years ago

@msand thanks for the response. as i need a scrollbar, the width increases dynamically. after increasing width thrice app is crashing.

for getting scrollbars, i am giving more width and overflow scroll to get a scrollbar. is that the right approach, kindly suggest.

msand commented 5 years ago

I would recommend striving to have the svg width and height to be at most as big as the native screen resolution on the device, and transform the content in response to pan/touch. Or, you might have use for what I've suggested here: https://github.com/react-native-community/react-native-svg/issues/573#issuecomment-432892772 and the excellent videos made by @wcandillon https://www.youtube.com/watch?v=KrsBXKr6gdg https://github.com/wcandillon/can-it-be-done-in-react-native

The technique boils down to using absolute positioning, to place a scrollview above the svg content that covers it completely, and placing an empty view inside the scrollview with the size set to the amount of overscroll you want available for scrolling in different directions. Finally, connecting the scroll events to transform the svg content below.

Alternatively, you can use something like https://www.npmjs.com/package/zoomable-svg https://github.com/react-native-community/react-native-svg/issues/374 This allows you to pinch and zoom to any size and get perfect vector graphics rendering, while keeping the bitmap size the same as the screen, and memory consumption relatively low.

If you allow your svg root size to grow, it'll keep eating more memory and make rendering slower as it needs to paint more pixels. So I would avoid having large bitmaps, unless the content is static and only needs to be rendered once and also fits in memory safely. In that case it can be the best performing way, as the scrolling merely needs to transform the bitmap around, rather than render vector graphics for each frame.