From mboxrd@z Thu Jan 1 00:00:00 1970 Delivered-To: chneukirchen@gmail.com Received: by 10.25.143.3 with SMTP id r3csp2667520lfd; Mon, 24 Aug 2015 16:17:07 -0700 (PDT) X-Received: by 10.50.72.6 with SMTP id z6mr18454602igu.65.1440458227106; Mon, 24 Aug 2015 16:17:07 -0700 (PDT) Return-Path: Received: from mail-ig0-x240.google.com (mail-ig0-x240.google.com. [2607:f8b0:4001:c05::240]) by mx.google.com with ESMTPS id ka10si7327698igb.53.2015.08.24.16.17.06 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Aug 2015 16:17:07 -0700 (PDT) Received-SPF: pass (google.com: domain of rack-devel+bncBD75LW742ECRB4OL52XAKGQENMS6EXI@googlegroups.com designates 2607:f8b0:4001:c05::240 as permitted sender) client-ip=2607:f8b0:4001:c05::240; Authentication-Results: mx.google.com; spf=pass (google.com: domain of rack-devel+bncBD75LW742ECRB4OL52XAKGQENMS6EXI@googlegroups.com designates 2607:f8b0:4001:c05::240 as permitted sender) smtp.mailfrom=rack-devel+bncBD75LW742ECRB4OL52XAKGQENMS6EXI@googlegroups.com; dkim=pass header.i=@googlegroups.com; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: by mail-ig0-x240.google.com with SMTP id jg10sf20065208igb.1; Mon, 24 Aug 2015 16:17:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :content-type:x-original-sender:x-original-authentication-results :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group :list-post:list-help:list-archive:sender:list-subscribe :list-unsubscribe; bh=s9OaKsaR5J1j2UgCPCBavZTHcWJ1yxkW3RMYU3eLqdY=; b=E8uv6b0sw2b/HDf0YXQ2L6Mm/sRPYQXbZE0B24RWuUljtRbONX9B7fivEcb8KSa10e qFajJt+skmjQp2Vqi421kpxDxFWcvx5OQK0SZHD/vwvGAhsYA+GcKYSLM3Hqj23Jn3bm VUFcj/suUTPzXsYAdgxjsS8I0fr8LiJ77ZwAb2AWzukE8zFobCRkVLVtkpomZq68wTNA Iu1PdZ0RSwVedxyKx+yNMlgHphzMuuKl14I2gsssPhGuEo+z5ofiKrIKyEZ+3528jUc+ M6AtBq1RQeB/OXrdrO65kpC5H0vH7QtJ9e0lYFQgOSgaSnOY3pBj4b7IbvPM+OjlgH0j gZHA== X-Received: by 10.50.66.205 with SMTP id h13mr290976igt.10.1440458226247; Mon, 24 Aug 2015 16:17:06 -0700 (PDT) X-BeenThere: rack-devel@googlegroups.com Received: by 10.50.60.34 with SMTP id e2ls1243811igr.4.canary; Mon, 24 Aug 2015 16:17:05 -0700 (PDT) X-Received: by 10.66.219.131 with SMTP id po3mr25142033pac.9.1440458225543; Mon, 24 Aug 2015 16:17:05 -0700 (PDT) Received: from mail-io0-x234.google.com (mail-io0-x234.google.com. [2607:f8b0:4001:c06::234]) by gmr-mx.google.com with ESMTPS id i10si1073175igh.3.2015.08.24.16.17.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Aug 2015 16:17:05 -0700 (PDT) Received-SPF: pass (google.com: domain of jftucker@gmail.com designates 2607:f8b0:4001:c06::234 as permitted sender) client-ip=2607:f8b0:4001:c06::234; Received: by mail-io0-x234.google.com with SMTP id v127so166971351iod.3 for ; Mon, 24 Aug 2015 16:17:05 -0700 (PDT) X-Received: by 10.107.3.149 with SMTP id e21mr19334749ioi.19.1440458225303; Mon, 24 Aug 2015 16:17:05 -0700 (PDT) MIME-Version: 1.0 References: <9d5cc646-0803-42c3-b118-f54a4cf8c6c0@googlegroups.com> <1440276882101.d5f8b2d3@Nodemailer> In-Reply-To: From: James Tucker Date: Mon, 24 Aug 2015 23:16:55 +0000 Message-ID: Subject: Re: Rack and memory usage ? To: rack-devel@googlegroups.com Content-Type: multipart/alternative; boundary=001a113eb35ed5479a051e16d0de X-Original-Sender: jftucker@gmail.com X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of jftucker@gmail.com designates 2607:f8b0:4001:c06::234 as permitted sender) smtp.mailfrom=jftucker@gmail.com; dmarc=pass (p=NONE dis=NONE) header.from=gmail.com Reply-To: rack-devel@googlegroups.com Precedence: list Mailing-list: list rack-devel@googlegroups.com; contact rack-devel+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: rack-devel@googlegroups.com X-Google-Group-Id: 486215384060 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , --001a113eb35ed5479a051e16d0de Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Sat, Aug 22, 2015 at 2:54 PM David Unric wrote: > Simple script takes about 6.2 MiB of memory with Ruby 2.2.3 on x86_64 > machine > > ruby --disable=3Dgems,rubyopt -e 'gets' > > so 31 - 5 - 6.2 =E2=89=88 20 MiB is for Rack > No. These are not comparable numbers. You've included random gems in there. Here: ~rack/rack % ruby -v ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux] ~rack/rack % ruby --disable=3Dgems -e 'system "ps -orss=3D #$$"' 6028 ~rack/rack % ruby --disable=3Dgems -Ilib -rrack -e 'system "ps -orss=3D #$$= "' 6244 That's 216KB. But I'm bending the truth too now, so in the interest of being honest, lets load ALL of rack: ~rack/rack % ruby --disable=3Dgems -e 'system "ps -orss=3D #$$"' 6060 ~rack/rack % ruby --disable=3Dgems -Ilib -rrack -e 'Dir["lib/**/*.rb"].each= { |f| begin; require f[%r%lib/(.*)$%, 1]; rescue LoadError; puts "skipped #{f}"; end}; system "ps -orss=3D #$$"' skipped lib/rack/session/memcache.rb skipped lib/rack/handler/thin.rb skipped lib/rack/handler/lsws.rb skipped lib/rack/handler/scgi.rb skipped lib/rack/handler/fastcgi.rb 20244 So that's ~14MB. HOWEVER, this is counting GC_MALLOC_LIMIT space, and the waste I produced loading things: :heap_live_num=3D>73962, :heap_free_num=3D>50543 Ruby 1.8.7, which the most recent releases dropped support for (you can fix this by undoing silly stylistic patches that I rejected for years), would only add about 10MB of heap fully loaded too. But lets look now at something a bit more real than just smash loading support for 9 servers, several authentication systems, session stuff, and maybe 10 (?) middleware that you're not using, and instead just load an actual minimal app: ~rack/rack % ruby --disable=3Dgems -Ilib -rrack -e 'require "rack/server"; Rack::Server.new.start; system "ps -orss=3D #$$"' example/lobster.ru [2015-08-24 15:36:35] INFO WEBrick 1.3.1 [2015-08-24 15:36:35] INFO ruby 2.0.0 (2013-06-27) [x86_64-linux] [2015-08-24 15:36:35] INFO WEBrick::HTTPServer#start: pid=3D16353 port=3D9= 292 ^C[2015-08-24 15:36:37] INFO going to shutdown ... [2015-08-24 15:36:37] INFO WEBrick::HTTPServer#start done. 16444 So now we're talking <10MB for a fully running application using webrick (which is not the smallest), on ruby 2.0 still, which is pretty fat. To just prove that, lets demonstrate some cgi.rb simplicity: ~rack/rack % env SCRIPT_NAME=3D/ HTTP_VERSION=3D1.0 SERVER_PORT=3D101010 SERVER_NAME=3Dcgi REQUEST_METHOD=3DGET ruby --disable=3Dgems -Ilib -rrack -= e 'require "rack/server"; Rack::Server.new.start; system "ps -orss=3D #$$"; p GC.stat' example/lobster.ru Status: 200 Content-Length: 592 Lobstericious!
                             ,.---._
                   ,,,,     /       `,
                    \\\\   /    '\_  ;
                     |||| /\/``-.__\;'
                     ::::/\/_
     {{`-.__.-'(`(^^(^^^(^ 9 `.=3D=3D=3D=3D=3D=3D=3D=3D=3D'
    {{{{{{ { ( ( (  (   (-----:=3D
     {{.-'~~'-.(,(,,(,,,(__6_.'=3D=3D=3D=3D=3D=3D=3D=3D=3D.
                     ::::\/\
                     |||| \/\  ,-'/,
                    ////   \ `` _/ ;
                   ''''     \  `  .'
                             `---'

flip!

crash!

13232 {:count=3D>4, :heap_used=3D>136, :heap_length=3D>138, :heap_increment=3D>2, :heap_live_num=3D>55223, :heap_free_num=3D>20068, :heap_final_num=3D>0, :total_allocated_object=3D>84612, :total_freed_object=3D>29389} So that's 7172KB, or about 7MB, and again, look at GC.stat there, a large part of the heap is free. Not saying this is bad but if there is a way how to push it lower. AFAIK > all ruby web servers are built upon Rack, not aware of any going its own > independent way. > Nope. Most webservers just implement the Rack SPEC. They shouldn't need any hard dependency on Rack itself. If memory serves, and I haven't been doing Rack/Ruby for a while, but Puma has no hard dependency on Rack. There are novelty servers such as the evented servers and so on that also implement other specs/protocols (normally their own). Thanks for link to derailed_benchmarks gem. Looks promising, definitely > would take a closer look at it. > > Btw. CRuby does not seem any worse then his "main" rival. Equivalent > script takes about 6.4 MiB with Python 2.7.10 and 7.7 MiB on Python 3.4.3= . > Well since YARV and the various GC tunings it's got a lot more heavy actually, and a lot more overhead and so on have landed in the stdlib (e.g. "packaged gems" and so on). This has a lot to do with the fact that the bulk of users for a long time have been running fat applications (e.g. rails). I still have some suuuuper old campfire daemons around that after many years of uptime are still sitting on a less than 10MB rss. *shrug* Some final notes: Rack::Server isn't all that light, it uses option parsers and maps env vars and so on, and creates some garbage. It may also be loading more than it needs to. You could setup a much lighter runtime by using the Handler API directly and configuring things in more memory efficient way (i.e. hardcoded). That's up to you. I also made a mistake in the above runs, but now can't be bothered to fix it, which is that they're all using the Rack development environment, which is loading middleware you probably don't need in production (e.g. rack/show_exceptions). You'll only really notice the difference if you trim the GC though, as there's more other garbage going on to expand the heap than is evident just avoiding a few more middleware - test it out yourself adding and removing the `-E none` parameter. I just re-ran with 2.2.3 and it seems to do better in not making excessive allocations: ~rack/rack 2.2.3 % ruby --disable=3Dgems -e 'system "ps -orss=3D #$$"' 6192 ~rack/rack 2.2.3 % ruby -Ilib -rrack -e 'Dir["lib/**/*.rb"].each { |f| begin; require f[%r%lib/(.*)$%, 1]; rescue LoadError; puts "skipped #{f}"; end}; system "ps -orss=3D #$$"' skipped lib/rack/session/memcache.rb skipped lib/rack/handler/thin.rb skipped lib/rack/handler/lsws.rb skipped lib/rack/handler/scgi.rb skipped lib/rack/handler/fastcgi.rb 20400 ~rack/rack 2.2.3 % env SCRIPT_NAME=3D/ HTTP_VERSION=3D1.0 SERVER_PORT=3D101= 010 SERVER_NAME=3Dcgi REQUEST_METHOD=3DGET ruby --disable=3Dgems -Ilib -rrack -= e 'require "rack/server"; Rack::Server.new.start; system "ps -orss=3D #$$"; p GC.stat' example/lobster.ru -E none Status: 200 Content-Length: 592 Lobstericious!
                             ,.---._
                   ,,,,     /       `,
                    \\\\   /    '\_  ;
                     |||| /\/``-.__\;'
                     ::::/\/_
     {{`-.__.-'(`(^^(^^^(^ 9 `.=3D=3D=3D=3D=3D=3D=3D=3D=3D'
    {{{{{{ { ( ( (  (   (-----:=3D
     {{.-'~~'-.(,(,,(,,,(__6_.'=3D=3D=3D=3D=3D=3D=3D=3D=3D.
                     ::::\/\
                     |||| \/\  ,-'/,
                    ////   \ `` _/ ;
                   ''''     \  `  .'
                             `---'

flip!

crash!

11268 {:count=3D>7, :heap_allocated_pages=3D>74, :heap_sorted_length=3D>75, :heap_allocatable_pages=3D>0, :heap_available_slots=3D>30163, :heap_live_slots=3D>29829, :heap_free_slots=3D>334, :heap_final_slots=3D>0, :heap_marked_slots=3D>13743, :heap_swept_slots=3D>8794, :heap_eden_pages=3D= >74, :heap_tomb_pages=3D>0, :total_allocated_pages=3D>74, :total_freed_pages=3D>= 0, :total_allocated_objects=3D>89907, :total_freed_objects=3D>60078, :malloc_increase_bytes=3D>712520, :malloc_increase_bytes_limit=3D>16777216, :minor_gc_count=3D>4, :major_gc_count=3D>3, :remembered_wb_unprotected_objects=3D>346, :remembered_wb_unprotected_objects_limit=3D>692, :old_objects=3D>10816, :old_objects_limit=3D>21634, :oldmalloc_increase_bytes=3D>1082840, :oldmalloc_increase_bytes_limit=3D>16777216} That's only 5MB fully loaded, after serving a request... You could also consider compiling with / LD_PRELOADING in jemalloc or tcmalloc or whatever, although that doesn't tend to make too much difference in heap size, it's more of a performance concern. Depends a bit on your platform and allocator(s), but there's a possibility these could save you relevant heap space at this level. ... blah ... I'll leave it there for now. You said you "measured" this and found that Rack was taking 26MB of 31. That doesn't really make sense, can you please provide a reproduction case? > > > On Saturday, August 22, 2015 at 10:54:44 PM UTC+2, richard schneeman wrot= e: > >> Just running `irb` with no libraries is 9.9 mb for me with Ruby 2.2.3. I= n >> Ruby 2.0 it's 17.9mb for me. Ruby is not known to be the most memory >> efficient language. >> >> I wrote a tool to help debug memor use in apps, check it out >> https://github.com/schneems/derailed_benchmarks >> >> You can run >> >> $ derailed bundle:mem >> >> To see the memory impact of all the gems you're using at require time. >> >> Here's more information: >> http://www.schneems.com/2015/05/11/how-ruby-uses-memory.html >> >> >> >> >> --- >> Richard Schneeman >> http://www.schneems.com >> >> >> >> On Sat, Aug 22, 2015 at 3:39 PM, David Unric wrote: >> > Hi, >>> >>> I'm asking if am I doing something wrong or is normal for a minimal rac= k >>> application have memory footprint over 25 MiB ? >>> >>> I'd like to reduce the memory usage as possible for deployment of a >>> Sinatra app on small x86 Linux NAS device. I did measured the memory us= age >>> and Rack occupies about excessive 26 from total of 31 MiB (the rest is = Thin >>> server + the app). >>> >>> Is there some Rack-lite or some trick how to shake-off unnecessary code >>> to get it on diet ? >>> >>> Thanks. >>> >>> -- >>> >>> --- >>> You received this message because you are subscribed to the Google >>> Groups "Rack Development" group. >>> >> To unsubscribe from this group and stop receiving emails from it, send a= n >>> email to rack-devel+...@googlegroups.com. >>> >> >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- > > --- > You received this message because you are subscribed to the Google Groups > "Rack Development" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rack-devel+unsubscribe@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > --=20 ---=20 You received this message because you are subscribed to the Google Groups "= Rack Development" group. To unsubscribe from this group and stop receiving emails from it, send an e= mail to rack-devel+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/d/optout. --001a113eb35ed5479a051e16d0de Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


On Sat= , Aug 22, 2015 at 2:54 PM David Unric <dunric29a@gmail.com> wrote:
Simple script takes about 6.2 MiB of memory with Rub= y 2.2.3 on x86_64 machine

=C2=A0=C2=A0=C2=A0 ruby --disable=3Dgems,r= ubyopt -e 'gets'

so=C2=A0 31 - 5 - 6.2 =E2=89=88 20 MiB is f= or Rack

No. These are not compara= ble numbers. You've included random gems in there.

=
Here:
~rack/rack % ruby -v
ruby 2.0.0p247 (20= 13-06-27 revision 41674) [x86_64-linux]
~rack/rack % ruby --disab= le=3Dgems -e 'system "ps -orss=3D #$$"'
=C2=A06= 028
~rack/rack % ruby --disable=3Dgems -Ilib -rrack -e 'syste= m "ps -orss=3D #$$"'
=C2=A06244
That's 216KB.

But I'm bending = the truth too now, so in the interest of being honest, lets load ALL of rac= k:

~rack/rack % ruby --disable=3Dgems -e '= ;system "ps -orss=3D #$$"' =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 6060
~rack/rack % ruby --disa= ble=3Dgems -Ilib -rrack -e 'Dir["lib/**/*.rb"].each { |f| beg= in; require f[%r%lib/(.*)$%, 1]; rescue LoadError; puts "skipped #{f}&= quot;; end}; system "ps -orss=3D #$$"'
skipped lib/= rack/session/memcache.rb
skipped lib/rack/handler/thin.rb
skipped lib/rack/handler/lsws.rb
skipped lib/rack/handler/scgi= .rb
skipped lib/rack/handler/fastcgi.rb
20244

So that's ~14MB. HOWEVER, this is counting GC_MAL= LOC_LIMIT space, and the waste I produced loading things:
:heap_l= ive_num=3D>73962, :heap_free_num=3D>50543

Ruby 1.8.7, which the most recent releases dropped support for (you can f= ix this by undoing silly stylistic patches that I rejected for years), woul= d only add about 10MB of heap fully loaded too.

Bu= t lets look now at something a bit more real than just smash loading suppor= t for 9 servers, several authentication systems, session stuff, and maybe 1= 0 (?) middleware that you're not using, and instead just load an actual= minimal app:

~rack/rack % ruby --disable=3Dg= ems -Ilib -rrack -e 'require "rack/server"; Rack::Server.new.= start; system "ps -orss=3D #$$"' example/lobster.ru
[2015-08-24 15:36:35] INFO =C2=A0WEBrick= 1.3.1
[2015-08-24 15:36:35] INFO =C2=A0ruby 2.0.0 (2013-06-27) [= x86_64-linux]
[2015-08-24 15:36:35] INFO =C2=A0WEBrick::HTTPServe= r#start: pid=3D16353 port=3D9292
^C[2015-08-24 15:36:37] INFO =C2= =A0going to shutdown ...
[2015-08-24 15:36:37] INFO =C2=A0WEBrick= ::HTTPServer#start done.
16444

So = now we're talking <10MB for a fully running application using webric= k (which is not the smallest), on ruby 2.0 still, which is pretty fat. To j= ust prove that, lets demonstrate some cgi.rb simplicity:

~rack/rack % env SCRIPT_NAME=3D/ HTTP_VERSION=3D1.0 SERVER= _PORT=3D101010 SERVER_NAME=3Dcgi REQUEST_METHOD=3DGET ruby --disable=3Dgems= -Ilib -rrack -e 'require "rack/server"; Rack::Server.new.sta= rt; system "ps -orss=3D #$$"; p GC.stat' example/lobster.ru
Status: 200
Content-Le= ngth: 592

<title>Lobstericious!</title>= ;<pre> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ,.---._
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0,,,, =C2=A0 =C2=A0 / =C2=A0= =C2=A0 =C2=A0 `,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 \\\\ =C2=A0 / =C2=A0 =C2=A0'\_ =C2=A0;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|||| /\/``-.__\;'
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0::::/\/_
=C2=A0 =C2=A0 = =C2=A0{{`-.__.-'(`(^^(^^^(^ 9 `.=3D=3D=3D=3D=3D=3D=3D=3D=3D'
<= div>=C2=A0 =C2=A0 {{{{{{ { ( ( ( =C2=A0( =C2=A0 (-----:=3D
=C2=A0= =C2=A0 =C2=A0{{.-'~~'-.(,(,,(,,,(__6_.'=3D=3D=3D=3D=3D=3D=3D= =3D=3D.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0::::\/\
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|||| \/\ =C2=A0,-'/,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ////= =C2=A0 \ `` _/ ;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0'''' =C2=A0 =C2=A0 \ =C2=A0` =C2=A0= .'
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0`---'
</pr= e><p><a href=3D'?flip=3Dleft'>flip!</a></p&= gt;<p><a href=3D'?flip=3Dcrash'>crash!</a></p&= gt;13232
{:count=3D>4, :heap_used=3D>136, :heap_length=3D&g= t;138, :heap_increment=3D>2, :heap_live_num=3D>55223, :heap_free_num= =3D>20068, :heap_final_num=3D>0, :total_allocated_object=3D>84612,= :total_freed_object=3D>29389}

So t= hat's 7172KB, or about 7MB, and again, look at GC.stat there, a large p= art of the heap is free.

Not saying this is bad but if there is a way how to push = it lower. AFAIK all ruby web servers are built upon Rack, not aware of any = going its own independent way.

No= pe. Most webservers just implement the Rack SPEC. They shouldn't need a= ny hard dependency on Rack itself.

If memory serve= s, and I haven't been doing Rack/Ruby for a while, but Puma has no hard= dependency on Rack.

There are novelty servers suc= h as the evented servers and so on that also implement other specs/protocol= s (normally their own).

=
Thanks for link to derailed_benchmarks gem. Looks promisin= g, definitely would take a closer look at it.

Btw. CRuby does not se= em any worse then his "main" rival. Equivalent script takes about= 6.4 MiB with Python 2.7.10 and 7.7 MiB on Python 3.4.3.
=

Well since YARV and the various GC tunings it's got= a lot more heavy actually, and a lot more overhead and so on have landed i= n the stdlib (e.g. "packaged gems" and so on). This has a lot to = do with the fact that the bulk of users for a long time have been running f= at applications (e.g. rails).

I still have some su= uuuper old campfire daemons around that after many years of uptime are stil= l sitting on a less than 10MB rss. *shrug*

Some fi= nal notes:

Rack::Server isn't all that light, = it uses option parsers and maps env vars and so on, and creates some garbag= e. It may also be loading more than it needs to. You could setup a much lig= hter runtime by using the Handler API directly and configuring things in mo= re memory efficient way (i.e. hardcoded). That's up to you.
<= br>
I also made a mistake in the above runs, but now can't be= bothered to fix it, which is that they're all using the Rack developme= nt environment, which is loading middleware you probably don't need in = production (e.g. rack/show_exceptions). You'll only really notice the d= ifference if you trim the GC though, as there's more other garbage goin= g on to expand the heap than is evident just avoiding a few more middleware= - test it out yourself adding and removing the `-E none` parameter.
<= div>
I just re-ran with 2.2.3 and it seems to do better in no= t making excessive allocations:

~rack/rack 2.= 2.3 % ruby --disable=3Dgems -e 'system "ps -orss=3D #$$"'=
=C2=A06192
~rack/rack 2.2.3 % ruby -Ilib -rrack -e = 9;Dir["lib/**/*.rb"].each { |f| begin; require f[%r%lib/(.*)$%, 1= ]; rescue LoadError; puts "skipped #{f}"; end}; system "ps -= orss=3D #$$"'
skipped lib/rack/session/memcache.rb
=
skipped lib/rack/handler/thin.rb
skipped lib/rack/handler/ls= ws.rb
skipped lib/rack/handler/scgi.rb
skipped lib/rack= /handler/fastcgi.rb
20400
~rack/rack 2.2.3 % env SCRIPT= _NAME=3D/ HTTP_VERSION=3D1.0 SERVER_PORT=3D101010 SERVER_NAME=3Dcgi REQUEST= _METHOD=3DGET ruby --disable=3Dgems -Ilib -rrack -e 'require "rack= /server"; Rack::Server.new.start; system "ps -orss=3D #$$"; = p GC.stat' example/lobster.ru -E none=
Status: 200
Content-Length: 592

<title>Lobstericious!</title><pre> =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 ,.---._
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0,,,, =C2=A0 =C2=A0 / =C2=A0 =C2=A0 =C2=A0 `,
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \\\\ = =C2=A0 / =C2=A0 =C2=A0'\_ =C2=A0;
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|||| /\/``-.__\;'
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0::::/\/_
=C2=A0 =C2=A0 =C2=A0{{`-.__.-'(`(^^(^^^(^ 9 `= .=3D=3D=3D=3D=3D=3D=3D=3D=3D'
=C2=A0 =C2=A0 {{{{{{ { ( ( ( = =C2=A0( =C2=A0 (-----:=3D
=C2=A0 =C2=A0 =C2=A0{{.-'~~'-.(= ,(,,(,,,(__6_.'=3D=3D=3D=3D=3D=3D=3D=3D=3D.
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0::::\/\
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|||| \/\ =C2=A0,-'/,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 //// =C2=A0 \ `` _/ ;
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0''= 9;' =C2=A0 =C2=A0 \ =C2=A0` =C2=A0.'
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0`---'
</pre><p><a href=3D'?flip= =3Dleft'>flip!</a></p><p><a href=3D'?flip= =3Dcrash'>crash!</a></p>11268
{:count=3D>7,= :heap_allocated_pages=3D>74, :heap_sorted_length=3D>75, :heap_alloca= table_pages=3D>0, :heap_available_slots=3D>30163, :heap_live_slots=3D= >29829, :heap_free_slots=3D>334, :heap_final_slots=3D>0, :heap_mar= ked_slots=3D>13743, :heap_swept_slots=3D>8794, :heap_eden_pages=3D>= ;74, :heap_tomb_pages=3D>0, :total_allocated_pages=3D>74, :total_free= d_pages=3D>0, :total_allocated_objects=3D>89907, :total_freed_objects= =3D>60078, :malloc_increase_bytes=3D>712520, :malloc_increase_bytes_l= imit=3D>16777216, :minor_gc_count=3D>4, :major_gc_count=3D>3, :rem= embered_wb_unprotected_objects=3D>346, :remembered_wb_unprotected_object= s_limit=3D>692, :old_objects=3D>10816, :old_objects_limit=3D>21634= , :oldmalloc_increase_bytes=3D>1082840, :oldmalloc_increase_bytes_limit= =3D>16777216}

That's only 5MB fully l= oaded, after serving a request...

You could also c= onsider compiling with / LD_PRELOADING in jemalloc or tcmalloc or whatever,= although that doesn't tend to make too much difference in heap size, i= t's more of a performance concern. Depends a bit on your platform and a= llocator(s), but there's a possibility these could save you relevant he= ap space at this level.

... blah ... I'll leav= e it there for now.

You said you "measured&qu= ot; this and found that Rack was taking 26MB of 31. That doesn't really= make sense, can you please provide a reproduction case?
=C2=A0


On Saturday, Au= gust 22, 2015 at 10:54:44 PM UTC+2, richard schneeman wrote:
Just running `irb` with no libraries is 9.9 mb for me with Ruby 2.2.3.= In Ruby 2.0 it's 17.9mb for me. Ruby is not known to be the most memor= y efficient language.=C2=A0

I wrote a tool to help debug memor use in apps, check it out https://github.com/schneems/derailed_benchmarks

You can run=C2=A0

$ derailed bundle:mem

To see the memory impact of all the gems you're using at require t= ime.=C2=A0





---
Richard Schneeman



On Sat, Aug 22, 2015 at 3:39 PM, Dav= id Unric <dunr...@gmail.com>= ; wrote:

Hi,

I'm asking if am I doing something wrong or= is normal for a minimal rack application have memory footprint over 25 MiB= ?

I'd like to reduce the memory usage as possible for deploymen= t of a Sinatra app on small x86 Linux NAS device. I did measured the memory= usage and Rack occupies about excessive 26 from total of 31 MiB (the rest = is Thin server + the app).

Is there some Rack-lite or some trick how= to shake-off unnecessary code to get it on diet ?

Thanks.

--

---
You received this message because you are subscribed to the Google Groups &= quot;Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to rack-devel+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
=

--

---
You received this message because you are subscribed to the Google Groups &= quot;Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to rack-devel+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--

---
You received this message because you are subscribed to the Google Groups &= quot;Rack Development" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to rack-dev= el+unsubscribe@googlegroups.com.
For more options, visit http= s://groups.google.com/d/optout.
--001a113eb35ed5479a051e16d0de--