Unstuck the unread count of Apple Messages app on Mac OS X

2015-02-20  |   |  apple   Mac OS X  

The text message synchronization between iOS and Mac OS X devices is very useful. That is until one of the unread count is stuck. There is nothing more irritating than a false unread badge.

It has happened to me on Apple Messages (iMessages) in Max OS X Yosemite. The message would "unread" itself in front of my eyes. I deleted the message, that solved that part.

But the unread count remained at 1. I fumed for a couple of days until I found the solution. Open your Terminal application (in Applications/Utilities) and type

killall Dock

The incorrect unread count disappeared. I can sleep now.

One line per idea - the feedback

2014-10-06  |   |  writing  

I wrote a bit more than a year ago on how to wrap lines for markup languages. I promised to give feedback on this experiment and specifically the use of one line per idea or clause.

Remember that to me, using one line per paragraph is problematic:

  • navigating through it is a bit cumbersome
  • reviewing a git diff is annoying when you need to scroll horizontally
  • editing one character leads to the whole paragraph as being seen edited in your favorite diff tool (at least if it is not that smart)

I am sad to say that the one line per idea concept does not work for me despite its big advantages on paper and its elegance. In practice, forcing myself to split each sentence in separate ideas lead to a slight writing slow down and cognitive dissonance. In a nutshell finding the natural split is not as easy as it sounds. And I could not really convince at least some of my colleagues enough of the benefits of this rule.

I settled for the following. One line per sentence. If the sentence is too long, one line per idea. And I won't mind if someones breaks the sentence at "odd" places.

It's one of those nice ideas that are not worth their cost.

I love what my Kindle did to my life

2014-08-29  |   |  book   productivity  

I have been a rather early adopter of ebook readers. The Sony PRS-505. But I gave it to my wife and moved on to read on my iPad instead: The whole buying books and moving them to the device was quite cumbersome and the iPad was good enough especially with the awesome Kindle app.

I physically met my colleagues a few month ago - no it does not happen very often - and two of them told me how they loved their physical Kindle device. I've been pondering the usefulness of yet another device in my life and finally decided to give it a go.

I bought the Amazon Kindle Paperwhite. Why? Well the price was not prohibitive. Why the Paperwhite? I'm a nocturnal beast, more than my wife an any rate. Why a Kindle? Now that gets interesting.

The reason this ebook reader changed my life can be summed up by:

  • I can read and only read on that thing
  • I can get my books instantly and wirelessly
  • I can read my books on multiple devices and they sync with each other
  • I can push non book content to the device wirelessly

Reading without interruption

That's a huge deal and that did bring back my pleasure of reading. An iPad is awesome but you get notified of tweets, facebook zombi parties, emails and all this chatter breaks your reading flow. I know you can disable notifications and put the device in Do Not Disturb.

But it is still oh so easy to jump in your emails for a quick check... and come back to reading 30 mins later having wasted your time. Same for twitter or the internet temptations. Now with the Kindle, you can go to the web but the experience is horrible enough to be a deterrent.

Frictionless book reading

I love DRM free formats. And I make a point of honor to free my encumbered digital assets if I can. And you can on Amazon books.

Still, it is undeniable that Amazon's experience with the Kindle devices, Kindle apps and Kindle shop ecosystem is just too good. No need to plug your device to a computer to get your books. And more importantly, I can stop reading a book on my Kindle, resume it on my iPhone while in the subway and go back to the Kindle in the evening. And the devices put me right where I stopped.

But wait there is more.

Selecting vs consuming

While I browse your twitter feed or whereever, I often see an interesting article that I want to read. But reading it now and stopping what I do long enough to read the article is extremely disruptive.

What I do instead is send to Instapaper articles I want to read. And ask Instapaper to send me a compiled list of unread articles to my Kindle device every day at 19:00 (that's 7:00 PM to our imperial friends). Instapaper integrates with a lot of apps including Twitter and you can use a Bookmarklet to push a page when browsing the web.

Tadaaaa! I have separated the selection process from the consumption process and I can be 100% into what I am doing and not sidetracked by the latest awesomeness the internet produces daily. I have this 20-30 mins of time in the evening (or most evenings at anyrate) when I read my pre-selected articles. The nice thing is that Instapaper inserts links you can use to mark an article as read (they call it archived). If you have not read all articles, they will simply come back the next day in the next compilation.

I'm super happy with my experience and can't recommend it enough. Even the basic WiFi-only will do you good. I had a defect on mine: the lighting was casting visible shadows (1cm by 1.5cm). That is not normal, just ask for a replacement, they are friendly about it.

By the way, I don't need to, but I do pay for the Instapaper service. They are both cheap and awesome.

Fiscalité globale en France

2014-05-17  |   |  francais   economy  

J'ai toujours été intéressé par la répartition de la fiscalité en fonction des revenus en France. Et là vous me dîtes :

Hum quoi?!

Si l'économie et la société ne vous intéresse pas en ce moment, passez votre chemin :)

Le système fiscal français est tellement compliqué qu'il est impossible d'avoir une image claire - sans parler des biais idéologiques. Je suis tombé sur un site qui donne une image plus globale que ce que l'on trouve d'habitude.

Ils prennent en compte:

  • l'impôt sur le revenu (dont la CSG / CRDS)
  • l'impôt sur le capital (impôt sur les sociétés, taxe foncière, ISF et droits de successions)
  • l'impôt sur la consommation (TVA principalement)
  • cotisations sociales et autres taxes sur les salaires + taxe d'habitation

Malheureusement les années Sarko et Hollande sont passées par là et les données sont assez obsolètes. Mais ce que montre leurs données, c'est que l'imposition globale est:

  • progressive jusqu'àu 50 ème percentile de revenu
  • plate du 50 ème au 99 ème percentile
  • franchement régréssive au delà

Si on exclut le dernier percentile, le système français serait assez proche de la "flat tax" avec une imposition globale entre 40 et 50% - sans les bénéfices de la flat tax correspondant à la simplicité :)

Imposition de la population française

Il faut s'entendre sur progressif / régressif. Ici ils en parlent en pourcentage du revenu et non pas en valeur absolue des impôts acquittés.

Ils proposent une alternative que je vous laisse découvrir à travers ces quelques pointeurs:

Sans rentrer dans le débat, le site est bien fait tant sur les chiffres existants que sur leurs propositions. Je vous encourage à aussi lire leur FAQ qui contient des infos supplémentaires ainsi que la section détracteurs sur leur page média.

J'ai quelques remarques cependant.

Chômeurs et retraités

Les chiffres mis en avant sur le site ne prennent pas en compte les chômeurs et retraités. Le système Français est alors "en moyenne" beaucoup plus progressif. J'imagine qu'ils voulaient montrer les inégalités en situation nominale de travail.

Niches fiscales

Leur nouvel impôt sur le revenu élimine les niches fiscales. Or ces niches fiscales ont en général un but : faire financer par les particuliers des objectifs de l'état - dons à des œuvres caritatives, investissement dans les zones défavorisées ou en manque d'investissement (DOM, TPE), construction immobilière dans les zones considérées en manque, réduction du travail non déclaré dit "travaux à domicile", etc. J'exclus ici les niches corporatistes - les niches c'est comme les chasseurs, y en a des bonnes et des mauvaises.

L'alternative est 1. une augmentation des impôts 2. une centralisation des décisions et des investissements par l'état qui devrait de fait grossir encore. Je préfère faire jouer le marcher et laisser ces décisions d'investissement aux millions de mains de la population.

Revenus et bénéfices?

Malheureusement, le revenu est considéré comme la somme du revenu salarial et patrimonial. Ce qui manque sont les aides indirectes dont les percentiles les plus défavorisés peuvent bénéficier - aides, gratuités - mais aussi les bénéfices des élus etc. Je ne sais pas si les revenus directs de type RSA sont inclus.

Coût de la vie

La disparité du coût de la vie entre les régions n'est pas pris en compte. Il est plus cher de vivre en Ile-de-France que dans le Limousin. Je n'ai jamais trouvé d'analyse assez fines qui combine:

  • le coût de la vie en proportion du revenu par géographie
  • le revenu net (apres impôts mais incluant toutes les aides y compris indirectes)

Revenus du capital

Mais le problème le plus important pour moi dans leur proposition est que le revenu du capital est taxé comme le revenu du travail. Ces deux types de revenus sont fondamentalement différents. Le risque de perte pour le capital est plus élevé et pas protégé par la société. La perte de capital veut dire la perte de générer ce fameux revenu. En poussant le bouchon, c'est l'équivalent de l'incapacité de travail sans les indemnités et sans le drame humain derrière bien sûr. François Saint-Cast et Bernard Zimmern appellent cela l'impôt-risque. Or c'est lui qui lance des idées, monte des boites et génère des emplois.

A noter que certains estiment que la taxation du revenu du capital revient à taxer le même argent plusieurs fois pour la même personne.

Il est loin d'être certain qu'une taxation similaire entre les revenus du travail et du capital soient une bonne idée.

So what ?

Bref, je trouve ce site intéressant pour son image de la fiscalité actuelle. Si vous avez d'autres sources sur ce sujet, laisser un commentaire.

L'initiative codeforfrance.org

2014-04-17  |   |  francais   change  

J'ai eu la chance d'interviewer Tariq Krim pour les cast codeurs et j'ai attrapé un peu de son virus / engouement pour changer les choses. Je suis très content qu'il ait lancé son initiative codeforfrance.org parce que c'est quelque chose qui me trottait dans la tête depuis l'interview.

Code for France, c'est quoi ?

Ben on ne sait pas trop vraiment. L'idée est probablement un mélange de:

  • Hacker la France pour la mettre à jour.
  • Code for America: aider les administrations et villes à corriger leur problèmes de code.
  • l'idée d'un répertoire de code où les administrations partageraient du code et des améliorations
  • proposer son aide en tant que citoyen
  • Bouger les frontières établies

Mais au fond, on s'en fout ce de que c'est aujourd'hui. Parce que ce que cela va être au final sera fait de ce que ce que les gens apporteront.

C'est pas un peu naïf ?

Totalement. Mais c'est justement ça qui est important !

Parce que l'attitude qui ne fonctionne pas c'est "ça ne marchera jamais", "qu'est-ce que tu veux que j'y fasse", "codeforfrance c'est même pas un titre en Français".

L'attitude qui fonctionne c'est "pourquoi pas". Il y a de plus en plus d'initiatives pourquoi pas en France (Programmatoo / devoxx4kids, les jduchesses, Devoxx). Et lancer une initiative un peu plus folle, un peu plus ambitieuse, un peu plus globale n'est que l'étape supérieure.

Et toi tu vas faire quoi ?

  1. Je me suis inscris.
  2. Je vais relayer ce lancement.
  3. Je propose mon savoir de constructeur de communautés (de code-urs).
  4. On verra après.

J'ai eu la chance de tomber dans l'open source, le communautaire et le partage de code quand j'étais petit. Je pense le comprendre de manière plus viscérale que la plupart. Si cela peut être utile, j'aiderai cette initiative avec mon expérience.

Moi aussi je veux faire ma part de citoyen et hacker la France. Ça use de se plaindre sans essayer de changer les choses.

C'est naïf ? Oui. Et ? Chiche.

Y'en a qu'on pas essayé. Ils ont eu des problèmes !

Aller sur codeforfrance.org.

Split a commit in two with Git

2014-04-14  |   |  tool   git  

Ever wanted a commit was actually made of two? Read on.

There are several reasons why you could wish a commit was actually made of several distinct ones:

  • because it makes the history more readable
  • because you are trying to reorder some commits and it creates nasty conflicts
  • just because

Merging two commits into one is easy: look for squashing for more info. While I am relatively versed in Git, I never knew how to efficiently do the opposite - splitting commits - until today.

Split a commit in two for the busy ones

Let's see the sequence first before explaining it

git rebase -i <oldsha1>
# mark the expected commit as `edit` (replace pick in front of the line), save a close
git reset HEAD^
git add ...
git commit -m "First part"
git add ...
git commit -m "Second part"
git rebase --continue

What did we do?

A detailed explanation

Interactive rebase

git rebase -i <oldsha1> opens a list of commits from oldsha1 to the latest commit in the branch. You can:

  • reorder them,
  • change the commit message of some,
  • squash (merge) two commits together,
  • and edit a commit.

We use edit in our case as we want to change the commit. Simply replace the pick word with edit on the line of the commit you want to split. When you save and close this "file", you will be placed at that commit in the command line.

Undo the actual commit

If you do a git status or a git diff, you will see that git places you right after the commit. What we want is to undo the commit and place the changes in our working area.

This is what git reset HEAD^ does: reset the state to the second last commit and leave the changes of the last commit in the working area. HEAD^ means the commit at HEAD minus 1.

Create the two commits

Next is simple gittery where you add changes and commit them the way you wish you had.

Finish the interactive rebasing

Make sure to finish the rebase by calling git rebase --continue. Hopefully, there won't be any conflicts and your history will contain the new commits.

A few more tips

This tip becomes much more powerful when you know how to add to the staging area parts of a file changes - instead of all the file changes that is.

The magic tool for that is git add -p myfile but it is quite arid. I recommend you use either GitX (Mac OS X, GUI) or tig (CLI). They offer a more friendly interactive way to add chunks of changes (up to line by line additions).

Another interesting tip for people that work on topic branches forked off master. You can do git rebase -i master which will list the commits between master and your branch. See my previous post on the subject for more info.

Can you spot the problem?

2014-03-28  |   |  Java  

I am working on Hibernate Search's ability to provide field bridge autodiscovery. I am usually pretty OK at getting a green bar on first run but I got out of luck today.

Can you spot the problem?

 org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion)
     at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:194)
     at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:707)
     at org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:387)
     at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:516)
     at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:105)
     at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
     at org.hibernate.search.test.bridge.ArrayBridgeTest.prepareData(ArrayBridgeTest.java:95)
     at org.hibernate.search.test.bridge.ArrayBridgeTest.setUp(ArrayBridgeTest.java:58)
     at org.hibernate.search.test.SearchTestCase.runBare(SearchTestCase.java:191)
     at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
     at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
 Caused by: org.hibernate.search.bridge.BridgeException: Exception while calling bridge#set
     class: org.hibernate.search.test.bridge.ArrayBridgeTestEntity
     path: dates
     at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper.buildBridgeException(ContextualExceptionBridgeHelper.java:101)
     at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper$OneWayConversionContextImpl.set(ContextualExceptionBridgeHelper.java:130)
     at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:449)
     at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:376)
     at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.createAddWork(DocumentBuilderIndexedEntity.java:292)
     at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:235)
     at org.hibernate.search.engine.impl.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:506)
     at org.hibernate.search.engine.impl.WorkPlan$PerClassWork.enqueueLuceneWork(WorkPlan.java:279)
     at org.hibernate.search.engine.impl.WorkPlan.getPlannedLuceneWork(WorkPlan.java:165)
     at org.hibernate.search.backend.impl.WorkQueue.prepareWorkPlan(WorkQueue.java:131)
     at org.hibernate.search.backend.impl.BatchedQueueingProcessor.prepareWorks(BatchedQueueingProcessor.java:73)
     at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.beforeCompletion(PostTransactionWorkQueueSynchronization.java:87)
     at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:191)
     ... 19 more
 Caused by: java.lang.ClassCastException: [Ljava.util.Date; cannot be cast to java.util.Date
     at org.hibernate.search.bridge.builtin.DateBridge.objectToString(DateBridge.java:90)
     at org.hibernate.search.bridge.builtin.impl.String2FieldBridgeAdaptor.set(String2FieldBridgeAdaptor.java:46)
     at org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper$OneWayConversionContextImpl.set(ContextualExceptionBridgeHelper.java:127)
     ... 30 more

Let me zoom a bit for you.

Caused by: java.lang.ClassCastException: [Ljava.util.Date; cannot be cast to java.util.Date

What? java.util.Date cannot be cast to java.util.Date???? That is usually a good sign that you're mixing classloaders and that the two objects comes from different ones. Except that in my unit test, I don't mess around with classloaders.

That's when it hit me. Do you see the [L? It means that the first type is not java.util.Date but java.util.Date[]. Now the ClassClastException makes perfect sense.


I'm a idiot or (preferred one) this error message needs a serious UX take over. The code is dying already. Why not take the few extra nanoseconds to represent the types in a readable way?

Caused by: java.lang.ClassCastException: java.util.Date[] cannot be cast to java.util.Date

I lost 5 minutes instead of 5 seconds. When you write your next error report or exception, think of the children! Or rather the poor souls that will have to use your library or code.

You can find more info on the [L syntax on stackoverflow.

Fixing Page Up and Page Down in Mac OS X Terminal.app

2013-12-12  |   |  Mac OS X   tool  

I am currently trying to move from iTerm to Terminal.app.

Terminal.app maps the Page Up/Down action to move around its buffer. This is quite annoying when you use text applications with their own buffer like mutt, vim, weechat etc).

Fortunately, there are two solutions, one easy and one more permanent.

Use Shift + Page Up

The easy one is to use Shift + Page Up instead of Page Up. Page Down works the same. The inconvenient is that you need to train your muscle memory.

Update the Terminal.app mapping

The more permanent one is to change the Terminal.app behavior.

Go in Preferences->Settings, select the right profile and go in the Keyboard tab. Find the Page Up entry and edit it to send text. Then type the ESC key followed by [5~. For good measure, I mapped Shift + Page Up to the Scroll Page Up action.
Do the same for page down with the following text ESC key followed by [6~.

You're all set.

Why did you start programming

2013-11-22  |   |  real life  

While discussing with a mom whose boy wants a computer for Christmas, the said "I suppose he wants to play games, what for otherwise?". To this I obviously replied "Programming!". The usual question popped up:

Why did you start (learning) programming?

I posed longer than usual this time along. This is not as trivial as it sounds.

Non programmers truly don't understand why someone would spend hours deep into this arcane thing. They would expect to spend time away from that damn machine or at least play games on it ; this could be considered fun at least, right?


Well, it's fairly complex but there is almost always a combination of the following:

  • it was the only way to achieve A (wrote my own game because I could not get ones off the shelves)
  • make this machine do what I want: empowerment and control in a deterministic world.
    Programmers tend to be slightly autistic when in the zone: determinism is really reassuring
  • fiddling with things. When you break dad's computer, you better have to find a way to fix it before he finds out. That required technical deep dives under adrenaline.

I asked the question (why did you start programming) to the twitter-sphere. Here is the compilation in 140 characters or less.

Raw data and other stories

for me it was ~10, staring at this C:> and knowing that I could control that beast to do what I wanted. - Emmanuel Bernard

Don't take it that I am a person that enjoys control over things. It was more having the power to do what I could imagine.

to have fun with my computer and display a rotating cube :) when I was 14 - Gerben Castel

Because it was the easiest way to render mathematics concrete - Fabrice Croiseaux

Apologies Fabrice but this on ought to be the weirdest ;)

I had to get a winmoden working with Linux in 96 - Fernando Meyer

I wanted to do like my older brother who could tell his programmable calculator what to do, and it would obey his orders! - Guillaume Laforge

Now Guillaume definitely is after power ;)

I was 8, I had a Commodore 64, and I wanted to know how I could tell it what to do. - Laurent Pireyn

for me it was seeing games on a C64 and thinking: I wanna make something like that! - Marvin

un pote qui m'a montré visual basic quand j'étais au lycée... le côté créatif et ludique m'a donné envie d'essayer - Loïc Descotte

got an old Mo5 from my cousins around 8 and had to learn how to use it to play games recorded on tapes... - benzonico

I got fascinated by those strange sentences on my VIC20 manual that could make my VIC20 display beautiful things on TV :) - Fabio Mancinelli

i was so excited to write my surname on the screen of our #zx81 - asicfr

11 in 1982, ZX81, Basic. Amazed to see a machine reproduce what I had written : a program. - Jean-Baptiste Briaud

In ~1980, Video games and computers were everywhere in Tokyo. First step was to play with, then to understand them. - Sébastien Douche

At 10, I was into drawing, he was into game programming. He's an architect (building), I'm a programmer. #BrotherAndSister - Corinne

Knowledge transfer at play ;)

My father brought a ZX81 in my lost village. - Didier Girard

Nothing else to do I guess.

As a kid I was not allowed to have a gaming console, only a C64. Had to build games myself. - Olivier Hubaut

age 9, tried format A: w/ ASM from P. Norton book, ended up fmting C:, my 1st app,1st OS reinstall & freaked out dad :) - Jo Voordeckers

I did that one too. I was annoyed by the . and .. in each directory so I deleted them! I deleted autoexec.bat and config.sys and ended up reinstalling the OS. Fiddling with things is core to programmer psyche.

The need to automate things. Write once, Run many times ! - Laurent

A lazy guy right there! Another trait of programmers.

Because computer didn't blame me when I failed vs sport/friends being a shy child. + Proud by "I did it myself" - Nicolas De loof

Despite what others think, a computer is a very predictable environment and is very reassuring for all these mildly autistic programmer minds.

@julienkauffmann qui me fait découvrir Delphi et comment changer la couleur du fond en cliquant sur un bouton. - Faulomi

I was ~11 and L'Ordinateur Individuel had a paper computer in it, with working memory registers and operators :) - David Dossot

Now that's hardcore.

as a child, it was amazing. "Look what I can do!". Getting your hands dirty. - Cédric Champeau

Craftsman spirit (power of creation). It starts with #Lego and continues with programming ;) - Daniel PETISME

code my own video game on my Alice computer. And feel powerful.... - Da Follower

Never touched a computer before entering CS. Seemed like perfect mix hard/applied science + creativity. Was fucking right! - Cyril Lacôte

At 7, my father bought a ZX81. It seemed funny, I learned "Print" ! 32 years after, still coding :) - Laurent CARON

read an article / subliminal images. Wrote a zx spectrum program to influence myself to work more in school:-)
it was in basic. Never got enough fps to make the message subliminal, so it failed... or not:-)
- chanezon

I guess that's another one in the lazy category. Pretty clever though :)

wanted to program my own adventure game on the ZX Spectrum, like The Hobbit - never got around to it though :-) - Thomas Conté

because you create things out of thin air. - Jean-Laurent Morlhon

Hum, I'm sure that's not what you thought when you started as a kid.

C++ when i was 14 to create modules for D&D neverwinter nights :) - Vivian Pennel

A man with a goal.

around ten, cpc464 as Christmas gift. I had to understand how games launched with load and run commands - Mat

i was 8 years old, my Father got a CPC464, i wanted Pac Man, my Father gave me a Basic book and told me "do it yourself" - Grégory M.

A dad with foresight. Though tough on his kid.

10 y.o.: 1st family computer. 11 y.o.: Word crash, lose 1h of homework. Next day: buy Linux CD, install. Then Bash, Perl... - Pierre Chapuis

Now imagine Mom and Dad's face when they tried to launch Word the next day :)

coder les musiques des séries tv en basic sur amstrad 6128 il y a ... 25 ans... k2000 supercopter & co #nostalgie - Alfred Almendra

Electronic music.

be able to hack into systems like the boy in "wargames" - Laurent Bristiel

Movies are bad for you kids, you have been warned! Lucky you did not for nuclear strike hacking.

at 6 wanted to help Man to land again on the moon, I thought the computer were the tool that build rockets like movies - Guillaume Wallet

Let me tell you, these moon guys knew their logarithmic tables by heart.

And you?

What's your story? Why did you start programming?

Notes sur les garbage collectors de la JVM

2013-09-22  |   |  java   francais  

Lors d'une discussion sur les différents garbage collectors disponibles sur la JVM, Rémi Forax est sorti de sa tanière et nous a fait un résumé que je trouve intéressant.

Un peu de contexte, on parlait des différents garbages collectors:

  • CMS (Concurrent Mark Sweep): implémentation "classique" dans la JVM HotSpot
  • G1: nouvelle implémentation dans la JVM HotSpot qui doit remplacer à terme CMS
  • C4: Azul's "pauseless" garbage collector

On parlait notamment de l'impact du temps pendant lequel les garbages collectors arrêtent le monde (stop the world).

Je laisse Rémi parler (édition mineure de ses propos et emphases personnelle):

Un GC ça marche en deux grosses phases, le marquage et la réclamation de la mémoire des objets non marqués. Pour qu'un GC soit rapide et efficace il faut essayer de faire les deux phases en même temps que le programme Java tourne. Autant pour le marquage on peut faire les choses pendant que le programme tourne autant pour la partie collection c'est plus délicat.

Il y a deux principaux algorithmes de collection,

  • le sweep où on alloue et désalloue comme malloc et free, dans ce cas les objets ne bougent pas en mémoire et on peut se retrouver avec du gruyère en mémoire
  • ou le compact qui consiste à recopier les objets vivants (les marqués) vers une autre zone.

L'algo de compact est meilleur mais:

  • pour bien marcher il faudrait 2 fois plus de mémoire que nécessaire, comme cela on a toujours la place de copier les objets d'un endroit à un autre.
  • comme on bouge les objets en mémoire, le programme Java ne peut pas tourner en même temps car il faut mettre à jour toutes les références de tous les objets entre leur ancienne adresse et leur nouvelle adresse.

De plus, réclamer la mémoire de tous le tas est lent si il est gros, donc on découpe le tas en zone, et on essaye de faire l'algo de GC sur peu de zones à la fois. Pour cela, il faut que l'on sache si une zone possède des pointeurs vers les autres zones (et à peu près où sont situés les référence). Dans ce cas le GC est incrémental et on utilise le mécanisme de protection de page pour tracker les références inter-zones.


Pour CMS, le tas est composé de plusieurs zones ordonnées, on fait des compacts pour passer les objets d'une zone à une autre et la dernière zone (assez grosse) ne fait pas de compact mais un sweep.
Cette organisation permet de faire un tracking des objets inter-zone plus simple, on regarde uniquement les pointeurs entre les zones les plus grandes vers les zones les plus petites donc on a pas besoin de coder vers quelle zone pointent les références.


Pour G1, on track les références inter-zones complets, donc toutes les zones font des compacts mais le mécanisme de tracking est plus compliqué. L'idée de G1 est que l'on indique le temps de collection maximum et qu'il adapte le nombre de zone qu'il faudra collecter en fonction. Donc on a des pause, mais si tous ce passe bien, leur durée est bornée.


Pour C4, l'idée est de faire la phase de collection de façon lazy, comme un compact normal, on bouge les objets en mémoire mais on ne ré-écrit pas les adresses, les références restent avec l'ancienne adresse mais on protège les pages contenant les anciens objet. Comme cela lorsque le programme cherche à accéder à un objet, si il possède une référence sur l'ancienne adresse, le mécanisme de protection mémoire émet un page fault. Et là il y a une astuce, lors d'un page fault, on sait à quelle adresse on a voulu lire et aussi quel instruction a merdé. Donc si lors de la génération du code assembleur on est capable pour chaque instruction qui peut générer un page fault de dire de quel champ de quel objet il s'agit, on peut mettre à jour la référence dans l'objet donc on aura pas de page fault au prochain accès de ce champ car la référence stockée dans le champ sera mise à jour.

Comme on utilise le mécanisme de protection mémoire de façon importante, l'implantation Linux de base n'est pas assez efficace, donc il faut patcher ton Linux. Le patch n'est pas petit car pour que ça dépote, la structure de données derrière est très spécifique et assez grosse ce qui fait que le patch a peut de chance d'intégrer un jour le trunk de linux.

Donc on a pas de pause comme pour CMS ou G1. En fait, il reste quelques pauses car il faut quand même faire un peu de synchro entre les différentes phases de l'algo de GC, mais lors de l'exécution du code on paye le surcout de mise à jour des références au fur et à mesure. De plus, il faut garder pas mal d'information et au niveau du code généré et au niveau de chaque zone pour être capable de faire l'association entre l'ancienne adresse et la nouvelle. Donc on a pas de pause, mais on a un overhead plus important qu'avec CMS ou G1 (G1 a déjà un overhead plus important que CMS à cause du tracking des références inter-zones).


En conclusion, pas de solution miracle, le GC à un overhead la question est quand veut-on le payer.

Name: Emmanuel Bernard
Bio tags: French, Open Source actor, Hibernate, (No)SQL, JCP, JBoss, Snowboard, Economy
Employer: JBoss by Red Hat
Resume: LinkedIn
Team blog: in.relation.to
Personal blog: No relation to
Microblog: Twitter, Google+
Geoloc: Paris, France