Having trouble reading this blog? Have a look at the original Lighthouse blog on Tumblr instead.

Mac OS X 10.9 (Mavericks) Memory Pressure

I bought my MacBook Pro in March 2013 with 4GB of RAM.  As a reasonably intensive user, it soon became clear that it was struggling with this amount of RAM and so a few months later I performed a DIY upgrade to 8GB, which I purchased from Crucial, who I can highly recommend.

Around the same time I also installed a third party memory manager to see how much memory I now had free.  To my surprise, the amount of free memory is now as low as before and it seemed I had to run the memory manager’s cleanup operation almost constantly to keep it looking reasonable.  To put it into context, as I’m writing this, I now have less than 80MB (yep, 1% of total available) free. Was I really going to have to upgrade once more, this time to 16GB?  It’s not an expensive or difficult thing to do, but it still seemed very surprising to me that I had to do it at all.

However, on further investigation it transpires that things are not all they seem to be.  Yes, there is only 80MB (actually, current instantaneous readout is 25MB!) free, but Mavericks operates differently to previous versions of OS X and actively grabs as much memory as it can, and distributes it to apps and processes as and when they need it.  The fact that the amount of free memory is so low is therefore deliberate.  Lack of memory only becomes a problem when it runs out completely and the OS has to rely on the hard drive as well.

The true test, rather than using a third party memory monitor, is Apple’s own Activity Monitor.  By viewing the Memory tab, the user can view the Memory Pressure.  As long as this is green, there is no problem, despite what the headline figure of free memory says.  I’m going to save the cash that I feared I would have to spend on a memory upgrade and put it towards something else.  HDD to SSD upgrade, anyone?

What's using that port on Mac OS X?

It happens to us all.  We run a web app locally when we’re developing or testing, get distracted and leave the app container running.  The next time we run the same time, we get the following message:

java.net.BindException: Address already in use

usually on port 8080.  The question is, how do we find out which process is using that port and how do we clear it?

On Mac OS X (and indeed on any Unix-style platform), we use the command:

sudo lsof -i:<port number>

This then brings up a load of useful information about which process is hogging our port including, most importantly, the PID.  From there it’s a simple case of either using the Activity Monitor to Force Quit the process, or from the command line use

kill <PID>

or

kill -9 <PID>

Eclipse BIRT Charting API examples

I’ve been playing with the Eclipse BIRT Charting APIs and have bought an excellent book called Integrating and Extending BIRT (3rd Edition) by Jason Weathersby, Tom Bondur, Iana Chatalbasheva. On trying out the Charting API examples, however, I came across a problem that took me a while to figure out.

The code example in the book looks like this:


    public static void main(String[] args) {
        Chart myChart = ChartWithAxesImpl.create();
        Serializer si = SerializerImpl.instance();
        try {
            si.write(myChart, new FileOutputStream(
                new File("<path_to_myChart.chart>")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

The book goes to some length to explain that a system environment variable of either

STANDALONE

or

BIRT_HOME="<path_to_Report_Engine>"

must be set.  However, the Birt code doesn’t actually try to read this variable!  Furthermore, if the Serializer can’t actually determine that it should be standalone, we get the following stack trace:


org.eclipse.birt.core.exception.BirtException: error.CannotStartupOSGIPlatform
	at org.eclipse.birt.core.framework.Platform.startup(Platform.java:81)
	at org.eclipse.birt.chart.util.PluginSettings.instance(PluginSettings.java:367)
	at org.eclipse.birt.chart.util.PluginSettings.instance(PluginSettings.java:335)
	at org.eclipse.birt.chart.model.impl.SerializerImpl.(SerializerImpl.java:70)
	at uk.co.lhsd.birt.chart.examples.SimpleChart.main(SimpleChart.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.NullPointerException
	at org.eclipse.birt.core.framework.jar.ServicePlatform.startup(ServicePlatform.java:205)
	at org.eclipse.birt.core.framework.jar.ServiceLauncher.startup(ServiceLauncher.java:80)
	at org.eclipse.birt.core.framework.Platform.startup(Platform.java:75)
	... 9 more

So, how do we tell the Serializer that we’re running standalone, when we can’t use the environment variable? Well, the standard response would be to configure it in a PlatformConfig object. But guess what? The Serializer doesn’t read the PlatformConfig object.  It references a PluginSettings object which in this case ignores the config completely.

The trick is to create a different PluginSettings instance and pass in a PlatformConfig to it.  When the Serializer is invoked, it uses the already-created PluginSettings instead of creating a new one.  The code then looks like this:


    public static void main(String[] args) {
        PlatformConfig config = new PlatformConfig();
        config.setProperty(PluginSettings.PROP_STANDALONE, "true");
        PluginSettings.instance(config);
        // Result of above method call is ignored.
        // However, PluginSettings.instance() called from Serializer
        // returns the previously created instance.
        Chart myChart = ChartWithAxesImpl.create();
        Serializer si = SerializerImpl.instance();
        try {
            si.write(myChart, new FileOutputStream(
                new File("<path_to_myChart.chart>")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Hey, presto - the Serializer starts and completes in standalone mode with no errors.

Java 7 on Mac OS X 10.9.2 Mavericks

Well, it seems that Apple do not want to make things too easy for us Java developers.  Its own support for Java expired with Java 6, and Java 7 is a much more manual affair.  Moreover there is no auto update path to get from one to the other.

In order to install the JDK on Mac OS X 10.9.2, I had to jump through the following hoops:

  • Download the installation disk image file here.
  • Run the installation, which will install the JDK in 
    /Library/Java/JavaVirtualMachines
    
  • From the command line, enter
    java -version
    
  • This may correctly update the CurrentJDK symlink… or it may not. If it doesn’t, you need to do the following:
  • Navigate to
    /System/Library/Frameworks/JavaVM.framework/Versions/
    
  • rm CurrentJDK
    
  • ln -s /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/ CurrentJDK
    

java -version should now return the required version. However, this doesn’t set the environment variable JAVA_HOME which is required by many apps. While java -version returns the version, JAVA_HOME contains the path to the JDK. To set it, do the following:

echo "export JAVA_HOME='/usr/libexec/java_home'" >> ~/.profile

That’s it.  You should now have Java 7 up and running as your default Java version on your Mac.

My first post

if you can read this, you’re either reading my post direct on Tumblr or you’re reading it on the Lighthouse Software Development web site, in which case my new Tumblr Stack for RapidWeaver is up and running.

RapidWeaver is a very cool, very extensible and flexible web site development tool for Mac. Check it out!

Custom Post Images