<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4059490850139758347</id><updated>2011-11-17T13:14:12.766-08:00</updated><category term='postgresql'/><category term='mysql'/><category term='java'/><category term='xfire'/><category term='work'/><category term='programming'/><title type='text'>DivideByZeroException</title><subtitle type='html'>Yet another blog named after a programming error</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4059490850139758347.post-7727438624415363462</id><published>2009-10-03T15:13:00.000-07:00</published><updated>2009-10-07T14:24:46.821-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>Implementing wait_timeout in PostgreSQL</title><content type='html'>In MySQL, the &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout"&gt;wait_timeout&lt;/a&gt; setting can be used to automatically close connections that have been inactive for a certain amount of time.&amp;nbsp; The default is 8 hours.&lt;br /&gt;&lt;br /&gt;Unfortunately, there is no equivalent in PostgreSQL (as of version 8.3).&amp;nbsp; However, it's easy to implement.&amp;nbsp; You just need to use the query_start column (of the &lt;a href="http://www.postgresql.org/docs/8.4/interactive/monitoring-stats.html#MONITORING-STATS-VIEWS-TABLE"&gt;pg_stat_activity&lt;/a&gt; view) to determine when a connection was last used.&lt;br /&gt;&lt;br /&gt;Here is an example using Bash:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#!/bin/bash&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WAIT_TIMEOUT_MINUTES="$1"&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/bin/psql -U postgres -t -c "SELECT procpid FROM pg_stat_activity WHERE (NOW() - query_start) &amp;gt; INTERVAL '$WAIT_TIMEOUT_MINUTES MINUTES'&amp;nbsp;AND current_query = '&amp;lt;IDLE&amp;gt;&lt;idle&gt;'" | xargs kill &lt;/idle&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This script takes the timeout as a command-line parameter, and then kills off any connections that have been sitting idle for too long.&lt;br /&gt;&lt;br /&gt;Add this to a cron job and you're all set.&lt;br /&gt;&lt;br /&gt;If you're using PostgreSQL 8.4, then you can do this entirely using SQL, thanks to the new &lt;a href="http://www.postgresql.org/docs/current/interactive/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminate_backend()&lt;/span&gt;&lt;/a&gt; function:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE (NOW() - query_start) &amp;gt; INTERVAL 60 MINUTES'&amp;nbsp;AND current_query = '&amp;lt;IDLE&amp;gt;&lt;idle&gt;'&lt;/idle&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This is especially useful if you're working in a Windows environment where there's no equivalent of &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;xargs&lt;/span&gt; (that I know of), or if you don't have access to a command line (i.e. you're making a remote connection using psql) and therefore can't use &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;kill&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Thanks to the anonymous commenter who pointed out an error in the original script.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4059490850139758347-7727438624415363462?l=dividebyzeroexception.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/7727438624415363462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4059490850139758347&amp;postID=7727438624415363462' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/7727438624415363462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/7727438624415363462'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/2009/10/implementing-waittimeout-in-postgresql.html' title='Implementing wait_timeout in PostgreSQL'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4059490850139758347.post-3252868406966749719</id><published>2008-09-11T09:09:00.000-07:00</published><updated>2008-09-11T09:12:08.217-07:00</updated><title type='text'>I've done this more times than I care to admit...</title><content type='html'>&lt;a href="http://orcorc.blogspot.com/2008/08/were-going-to-need-another-timmy.html"&gt;http://orcorc.blogspot.com/2008/08/were-going-to-need-another-timmy.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4059490850139758347-3252868406966749719?l=dividebyzeroexception.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/3252868406966749719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4059490850139758347&amp;postID=3252868406966749719' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/3252868406966749719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/3252868406966749719'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/2008/09/ive-done-this-more-times-than-i-care-to.html' title='I&apos;ve done this more times than I care to admit...'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4059490850139758347.post-609095219447676387</id><published>2008-08-14T11:16:00.000-07:00</published><updated>2008-08-14T11:42:49.340-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='xfire'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>XFire interface proxies</title><content type='html'>As I wrote in &lt;a href="/2008/08/dangers-of-micro-benchmarking.html"&gt;my last post&lt;/a&gt;, we are currently working on a project where we have a queue with a &lt;span style="font-style:italic;"&gt;huge&lt;/span&gt; number of Java objects, and we need to squeeze every last bit of memory out of them.    Even after the previous optimization, it still seemed like the memory usage was much higher than it should have been.&lt;br /&gt;&lt;br /&gt;One thing I didn't mention is that the objects in the queue are coming in via Web service calls, marshaled by &lt;a href="http://xfire.codehaus.org/"&gt;XFire&lt;/a&gt;'s &lt;a href="http://xfire.codehaus.org/Aegis+Binding"&gt;Aegis binding&lt;/a&gt;.  No big deal, right?  Except that the objects are exposed in our API using Java interfaces, not concrete classes.  In other words, our code is something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface Node { ... }&lt;br /&gt;&lt;br /&gt;public class NodeImpl implements Node { ... }&lt;br /&gt;&lt;br /&gt;public class OurService {&lt;br /&gt;  public void enqueueNode(Node node) { ... }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;How does XFire handle this?  At first glance, it doesn't seem like a problem, but when XFire is converting a SOAP call into Java objects, &lt;span style="font-style:italic;"&gt;how does it know what type of object to instantiate&lt;/span&gt;?  XFire doesn't magically know that our implementation of the Node interface is NodeImpl.  And in fact, early versions of XFire did not support using interfaces in a service's API.&lt;br /&gt;&lt;br /&gt;The trick XFire uses since version 1.0 RC (way back when) is to create a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html"&gt;dynamic proxy class&lt;/a&gt;.  This is really great because it allows interfaces to "just work", but it carries a huge amount of overhead.&lt;br /&gt;&lt;br /&gt;Now, back to our queue.  If these proxies are taking so much memory, what can we do about it?  Do we have to change our API to use concrete classes?  Once again, XFire comes to the rescue.  You can use XFire settings to configure your service so that, even though you use interfaces, &lt;span style="font-style:italic;"&gt;XFire will always instantiate the class that you tell it to&lt;/span&gt;.  The details are all &lt;a href="http://xfire.codehaus.org/Aegis+and+Interfaces"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now for the results:  using dynamic proxies, our queue could hold about 1,000 elements (using a JVM configured with a maximum heap size of 13 GB).  After the change was made, our queue could hold 10,000 elements - a &lt;span style="font-style:italic;"&gt;10x&lt;/span&gt; increase!  Now that's what I'm talking about :-).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4059490850139758347-609095219447676387?l=dividebyzeroexception.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/609095219447676387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4059490850139758347&amp;postID=609095219447676387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/609095219447676387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/609095219447676387'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/2008/08/xfire-interface-proxies.html' title='XFire interface proxies'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4059490850139758347.post-7477180252289634651</id><published>2008-08-08T09:53:00.000-07:00</published><updated>2008-08-08T09:58:53.110-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The dangers of micro-benchmarking</title><content type='html'>This week I started on a project where we needed to optimize the memory usage of a Java queue with a very, very large number of objects.  Right away I noticed that the objects we are putting in the queue use "wrapper objects" for native types like long, int, etc.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Node {&lt;br /&gt;  public java.lang.Long oneValue;&lt;br /&gt;  public java.lang.Long anotherValue;&lt;br /&gt;  // etc.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Changing these to use regular primitives seemed like a great way to save memory, so I wrote up a little micro-benchmark:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class OldNode {&lt;br /&gt;  public java.lang.Long oneValue;&lt;br /&gt;  // etc.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class NewNode {&lt;br /&gt;  public long oneValue;&lt;br /&gt;  // etc.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;  List nodes = new ArrayList();&lt;br /&gt;  try {&lt;br /&gt;    OldNode node = new OldNode();&lt;br /&gt;    node.oneValue = 1L; // take advantage of Java 5 auto-boxing&lt;br /&gt;    nodes.add(node);&lt;br /&gt;  } catch (OutOfMemoryError e) {&lt;br /&gt;    System.out.println("Out of memory.  Size: " + nodes.size());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // And then repeat the same thing with NewNode&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When I ran this test, the old node class came out ahead of the new node class!  In other words, I was able to add around 300,000 of the old objects to the list before running out of memory, but I could only add around 280,000 of the new objects.  Obviously, this didn't make any sense.&lt;br /&gt;&lt;br /&gt;The reason is easy to spot if you know how auto-boxing works.  The following line:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;node.oneValue = 1L; // take advantage of Java 5 auto-boxing&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;gets converted by the Java compiler to:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;node.oneValue = Long.valueOf(1L);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and the implementation of Long.valueOf() (at least in the Sun JVM) uses cached values for -128 to 127.  So the old node class was re-using a single Long object for every instance!  Obviously this uses a lot less memory.&lt;br /&gt;&lt;br /&gt;Once I changed the benchmark to use Rand.nextLong() to generate the values, the new node class came out ahead, using about 40% of the memory that the old class used.&lt;br /&gt;&lt;br /&gt;The larger picture is that if you write micro-benchmarks, you have to approximate real-world data.  The part that made my original test fail was taking the easy way out and using all 0's.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4059490850139758347-7477180252289634651?l=dividebyzeroexception.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/7477180252289634651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4059490850139758347&amp;postID=7477180252289634651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/7477180252289634651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/7477180252289634651'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/2008/08/dangers-of-micro-benchmarking.html' title='The dangers of micro-benchmarking'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4059490850139758347.post-4127907878966722496</id><published>2008-08-08T09:51:00.000-07:00</published><updated>2008-08-08T09:53:09.660-07:00</updated><title type='text'>Hello world!</title><content type='html'>I'm starting a new blog to post the random stuff that I come up with at work and otherwise.  Hope you enjoy it :-).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4059490850139758347-4127907878966722496?l=dividebyzeroexception.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dividebyzeroexception.blogspot.com/feeds/4127907878966722496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4059490850139758347&amp;postID=4127907878966722496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/4127907878966722496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4059490850139758347/posts/default/4127907878966722496'/><link rel='alternate' type='text/html' href='http://dividebyzeroexception.blogspot.com/2008/08/hello-world.html' title='Hello world!'/><author><name>Matt</name><uri>http://www.blogger.com/profile/07858478547240184136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
