Pixplicity / sharp

Scalable vector graphics for Android
Apache License 2.0
1.03k stars 116 forks source link

Memory usage? #34

Open AndroidDeveloperLB opened 7 years ago

AndroidDeveloperLB commented 7 years ago

Any information about memory usage of this library? Is it efficient? Suppose we take the sample of Cartman, How much does it take in heap memory, compared to the same sample without loading anything?

I tried to modify the sample, and I think it uses about 4MB :

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_svg_demo);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mImageView = (ImageView) findViewById(R.id.iv_image);
        mButton = (Button) findViewById(R.id.bt_button);
        printMemStats();
        mSvg = Sharp.loadResource(getResources(), R.raw.cartman);
        // If you want to load typefaces from assets:
        //          .withAssets(getAssets());

        // If you want to load an SVG from assets:
        //mSvg = Sharp.loadAsset(getAssets(), "cartman.svg");
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                reloadSvg(true);
            }
        });

        mAttacher = new PhotoViewAttacher(mImageView);
        mAttacher.setMaximumScale(10f);

        reloadSvg(false);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                printMemStats();
            }
        },2000);

    }

    private void printMemStats() {
        final long availableMemInBytes = getAvailableMemInBytes();
        final long maxMemInBytes = getMaxMemInBytes();
        final long usedMemInBytes = maxMemInBytes - availableMemInBytes;
        final long usedMemInPercentage = usedMemInBytes * 100 / maxMemInBytes;
        Log.d("AppLog", "used: " + Formatter.formatShortFileSize(this, usedMemInBytes) + " / " +
                Formatter.formatShortFileSize(this, maxMemInBytes) + " (" + usedMemInPercentage + "%)");
    }

    public static long getMaxMemInBytes() {
        return Runtime.getRuntime().maxMemory();
    }

    public static long getAvailableMemInBytes() {
        // find available memory
        final Runtime runtime = Runtime.getRuntime();
        final long usedMem = runtime.totalMemory() - runtime.freeMemory();
        final long maxHeapSize = runtime.maxMemory();
        final long result = maxHeapSize - usedMem;
        return result;
    }
pflammertsma commented 7 years ago

That's a fantastic question. There weren't any considerations made in memory efficiency, but truthfully nothing comes to mind for ways of improving it.

Your metrics look good to me, but it's likely also dependant on the zoom level and screen density.

On Sun, Feb 26, 2017, 14:11 AndroidDeveloperLB notifications@github.com wrote:

Any information about memory usage of this library? Is it efficient? Suppose we take the sample of Cartman, How much does it take in heap memory, compared to the same sample without loading anything?

I tried to modify the sample, and I think it uses about 4MB :

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_svg_demo);

   Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
   setSupportActionBar(toolbar);

   mImageView = (ImageView) findViewById(R.id.iv_image);
   mButton = (Button) findViewById(R.id.bt_button);
   printMemStats();
   mSvg = Sharp.loadResource(getResources(), R.raw.cartman);
   // If you want to load typefaces from assets:
   //          .withAssets(getAssets());

   // If you want to load an SVG from assets:
   //mSvg = Sharp.loadAsset(getAssets(), "cartman.svg");
   mButton.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           reloadSvg(true);
       }
   });

   mAttacher = new PhotoViewAttacher(mImageView);
   mAttacher.setMaximumScale(10f);

   reloadSvg(false);
   new Handler().postDelayed(new Runnable() {
       @Override
       public void run() {
           printMemStats();
       }
   },2000);

}

private void printMemStats() { final long availableMemInBytes = getAvailableMemInBytes(); final long maxMemInBytes = getMaxMemInBytes(); final long usedMemInBytes = maxMemInBytes - availableMemInBytes; final long usedMemInPercentage = usedMemInBytes * 100 / maxMemInBytes; Log.d("AppLog", "used: " + Formatter.formatShortFileSize(this, usedMemInBytes) + " / " + Formatter.formatShortFileSize(this, maxMemInBytes) + " (" + usedMemInPercentage + "%)"); }

public static long getMaxMemInBytes() { return Runtime.getRuntime().maxMemory(); }

public static long getAvailableMemInBytes() { // find available memory final Runtime runtime = Runtime.getRuntime(); final long usedMem = runtime.totalMemory() - runtime.freeMemory(); final long maxHeapSize = runtime.maxMemory(); final long result = maxHeapSize - usedMem; return result; }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Pixplicity/sharp/issues/34, or mute the thread https://github.com/notifications/unsubscribe-auth/AARdYx9gdwlZ5hh8gnTpJlkabsLKk3WEks5rgYgUgaJpZM4MMZPQ .

AndroidDeveloperLB commented 7 years ago

But why would it take so much ? I mean, shouldn't it be very low in memory usage, seeing that it's just drawing according to some rules (draw line here, draw gradient there, etc...) , instead of using pixels data?

pflammertsma commented 7 years ago

Ultimately pixel data is stored somewhere since the vector is drawn onto a canvas. As a result we get uncompressed ARGB, 4 bytes per pixel. At full HD, that's 1920×1080×4, roughly 8MB.

That's my hypothesis, at least.

On Sun, Feb 26, 2017, 14:35 AndroidDeveloperLB notifications@github.com wrote:

But why would it take so much ? I mean, shouldn't it be very low in memory usage, seeing that it's just drawing according to some rules (draw line here, draw gradient there, etc...) , instead of using pixels data?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/Pixplicity/sharp/issues/34#issuecomment-282560061, or mute the thread https://github.com/notifications/unsubscribe-auth/AARdY1m6oCPiQwx3Xu4RQnrxHsORUTi1ks5rgY2kgaJpZM4MMZPQ .

AndroidDeveloperLB commented 7 years ago

Oh, this probably explains why I got similar result on VectorDrawable. But, on new Android versions (7.1.x), it seems VectorDrawable barely changes the memory usage (if at all). Maybe they've optimized it somehow?

pflammertsma commented 7 years ago

Possibly, but I really couldn't say. If you can instead use VectorDrawable, you certainly should.

On Sun, Feb 26, 2017, 14:42 AndroidDeveloperLB notifications@github.com wrote:

Oh, this probably explains why I got similar result on VectorDrawable. But, on new Android versions (7.1.x), it seems VectorDrawable barely changes the memory usage (if at all). Maybe they've optimized it somehow?

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/Pixplicity/sharp/issues/34#issuecomment-282560508, or mute the thread https://github.com/notifications/unsubscribe-auth/AARdY8SjwiBRdPsoX7sJHvieTlXAMBsCks5rgY87gaJpZM4MMZPQ .

AndroidDeveloperLB commented 7 years ago

Sadly, it has its own disadvantages. Lack of ways to use it, and lack of features to draw (can't draw gradients and texts, for example).