-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2019-06-01-long-time-no-java.html
682 lines (613 loc) · 36.5 KB
/
2019-06-01-long-time-no-java.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="/theme/css/elegant.prod.9e9d5ce754.css" media="screen">
<link rel="stylesheet" type="text/css" href="/theme/css/custom.css" media="screen">
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<meta name="author" content="jin" />
<meta name="description" content="I have not written Java in more than three years. I started working on Java applications earlier this year. This post documents some of the Java quirks, tooling, and best practices that caught my eyes in the first 3 months of meeting Java again. It is intended to be useful …
" />
<meta name="twitter:creator" content="@jinfwhuang">
<meta property="og:type" content="article" />
<meta name="twitter:card" content="summary">
<meta name="keywords" content="java, misc, " />
<meta property="og:title" content="Long Time No Java "/>
<meta property="og:url" content="/2019-06-01-long-time-no-java" />
<meta property="og:description" content="I have not written Java in more than three years. I started working on Java applications earlier this year. This post documents some of the Java quirks, tooling, and best practices that caught my eyes in the first 3 months of meeting Java again. It is intended to be useful …" />
<meta property="og:site_name" content="Jin's Notes" />
<meta property="og:article:author" content="jin" />
<meta property="og:article:published_time" content="2019-06-01T00:00:00-07:00" />
<meta name="twitter:title" content="Long Time No Java ">
<meta name="twitter:description" content="I have not written Java in more than three years. I started working on Java applications earlier this year. This post documents some of the Java quirks, tooling, and best practices that caught my eyes in the first 3 months of meeting Java again. It is intended to be useful …">
<meta property="og:image" content="/images/android-chrome-192x192.png" />
<meta name="twitter:image" content="/images/android-chrome-192x192.png" >
<title>Long Time No Java · Jin's Notes
</title>
<link rel="shortcut icon" href="/theme/images/favicon.ico" type="image/x-icon" />
<link rel="icon" href="/theme/images/apple-touch-icon-152x152.png" type="image/png" />
<link rel="apple-touch-icon" href="/theme/images/apple-touch-icon.png" type="image/png" />
<link rel="apple-touch-icon" sizes="57x57" href="/theme/images/apple-touch-icon-57x57.png" type="image/png" />
<link rel="apple-touch-icon" sizes="72x72" href="/theme/images/apple-touch-icon-72x72.png" type="image/png" />
<link rel="apple-touch-icon" sizes="76x76" href="/theme/images/apple-touch-icon-76x76.png" type="image/png" />
<link rel="apple-touch-icon" sizes="114x114" href="/theme/images/apple-touch-icon-114x114.png" type="image/png" />
<link rel="apple-touch-icon" sizes="120x120" href="/theme/images/apple-touch-icon-120x120.png" type="image/png" />
<link rel="apple-touch-icon" sizes="144x144" href="/theme/images/apple-touch-icon-144x144.png" type="image/png" />
<link rel="apple-touch-icon" sizes="152x152" href="/theme/images/apple-touch-icon-152x152.png" type="image/png" />
<link rel="apple-touch-icon" sizes="152x152" href="/theme/images/apple-touch-icon-180x180.png" type="image/png" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-207279664-1', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<div id="content">
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="/"><span class=site-name><span style="color:black;">Jin's Notes</span></span></a>
<div class="nav-collapse collapse">
<ul class="nav pull-right top-menu">
<li >
<a href=
"/"
>Home</a>
</li>
<!-- <li ><a href="/categories">Categories</a></li>-->
<li ><a href="/tags">Tags</a></li>
<li ><a href="/archives">Archives</a></li>
<li><form class="navbar-search" action="/search" onsubmit="return validateForm(this.elements['q'].value);"> <input type="text" class="search-query" placeholder="Search" name="q" id="tipue_search_input"></form></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span1"></div>
<div class="span10">
<article itemscope>
<div class="row-fluid">
<header class="page-header span10 offset2">
<h1>
<a href="/2019-06-01-long-time-no-java">
Long Time No Java
</a>
</h1>
</header>
</div>
<div class="row-fluid">
<div class="span2 table-of-content">
<nav>
<h4>Contents</h4>
<div class="toc">
<ul>
<li><a href="#java-quirks">Java Quirks</a></li>
<li><a href="#library-choices">Library Choices</a></li>
<li><a href="#dependency">Dependency</a></li>
<li><a href="#tooling">Tooling</a></li>
<li><a href="#application-setup">Application Setup</a></li>
<li><a href="#style">Style</a></li>
<li><a href="#fun-reads-in-java">Fun reads in Java</a></li>
</ul>
</div>
</nav>
</div>
<div class="span8 article-content">
<p>I have not written Java in more than three years. I started working on Java applications earlier this year. This post documents some of the Java quirks, tooling, and best practices that caught my eyes in the first 3 months of meeting Java again. It is intended to be useful for others (and my future self) who experience some gap years with Java. The items and references mentioned here are not comprehensive. They are meant to be entry points for the interested readers. I might write detailed posts about specific topics in the future.</p>
<p><br/> </p>
<h4 id="java-quirks">Java Quirks<a class="headerlink" href="#java-quirks" title="Permanent link">¶</a></h4>
<ul>
<li>
<p>Effective Java (<a href='#bloch2018' id='ref-bloch2018-1'>
Blo18
</a>). This is the best refresher. After many years, this is still the best book on the best practices of Java programming. This updated version offers guidelines on the functional features on Lamda and Streams. This had been a must-read, and it still is. </p>
</li>
<li>
<p><em>Pseudo</em> pass by value. I could not choose the exact semantics of parameters passing, e.g. by value, by reference, and by pointer, as I would in <a href="http://www.cplusplus.com/articles/z6vU7k9E/">c++</a>. The mode of parameter passing is fixed in Java. It is technically always <a href="https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12">pass by value</a>, but that is confusing terminology. For object parameters, it is effectively pass by value of the pointer. If the variable is reassigned, the original value is unaffected. If the object’s members are reassigned, the original value are affected. For primitive types, it is pass by value. If the variable is reassigned, the original value is unaffected.</p>
</li>
<li>
<p>Check Exceptions. See <a href='#checkedexception2014' id='ref-checkedexception2014-1'>
che14
</a>, <a href='#bloch2018' id='ref-bloch2018-2'>
Blo18
</a></p>
<p>I still do not have a strong opinion on this feature. In many code bases, it feels pretty random on how folks are passing up and down the chain of checked exception. In rare cases when I am writing a small library, it makes sense to indicate expected issues through checked exception. This features feels awkward. Everyone has an opinion on it in code reviews and uses up a lot of back and forths. I am not convinced one way or the other. I recommend minimize its usage as much as possible. I would not object to a style guide and linting tool that warn against all checked exceptions.</p>
</li>
<li>
<p>Prefer protobuf or thrift over Java serialization.</p>
</li>
<li>
<p>Prefer StringBuilder. StringBuffer is synchronized. StringBuilder is not.</p>
</li>
<li>
<p>Use file utilities from Guava or Apache commons</p>
</li>
<li>
<p><a href="https://blog.joda.org/2014/02/exiting-jvm.html"><span class="caps">JVM</span> exiting</a> could be tricky.</p>
</li>
<li>
<p>Java class path <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/findingclasses.html">ordering matters</a></p>
</li>
<li>
<p><a href="https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java">AtomicInteger</a> is lock free, using compare-and-swap (<span class="caps">CAS</span>) hardware instruction in x86. <code>synchronize</code> is lock based. However, <code>synchronize</code> only uses <span class="caps">CAS</span> and work similarly as a lock-free algorithm when there is no contention. If contended, it uses spin locking and then fall back to system calls (e.g. futex). See <a href='#thompson2011' id='ref-thompson2011-1'>
Tho11
</a>, <a href='#thompson2011_2' id='ref-thompson2011_2-1'>
tho11
</a>, <a href='#dice2006' id='ref-dice2006-1'>
Dic06
</a>, <a href='#goetz2004' id='ref-goetz2004-1'>
Goe04
</a>, <a href='#atomicinteger2014' id='ref-atomicinteger2014-1'>
ato14
</a></p>
</li>
<li>
<p>The utility in Concurrent Collections makes extensive use of lock free algorithms</p>
</li>
<li>
<p>Java non-blocking <span class="caps">IO</span> is not the same as Asynchronous <span class="caps">IO</span>. <span class="caps">AIO</span> is confusingly termed <code>NIO.2</code>. See <a href="https://stackoverflow.com/questions/25537675/java-what-exactly-is-the-difference-between-nio-and-nio-2">disambiguiation</a> and this <a href="https://www.ibm.com/developerworks/java/library/j-nio2-1/index.html">post</a>.</p>
</li>
<li>
<p>Java has good support for <a href="https://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html">memory-mapped</a> file <span class="caps">IO</span></p>
</li>
<li>
<p>Java Concurrency in Practice (<a href='#goetz2006' id='ref-goetz2006-1'>
Goe06
</a>). Going through this book, even just the table of contents, is a good use of time to get a good download on most of the core concurrent concepts in Java. This does not include actor model made popular by Scala and Akka.</p>
</li>
</ul>
<p><br/></p>
<h4 id="library-choices">Library Choices<a class="headerlink" href="#library-choices" title="Permanent link">¶</a></h4>
<ul>
<li>
<p><a href="https://github.com/google/guava/wiki">Google Guava</a>: Its collection idioms are still the best.</p>
</li>
<li>
<p><a href="https://github.com/FasterXML/jackson">Jackson</a> for json</p>
</li>
<li>
<p>Http Client Library: If I am developing in Java 11, I would go with the client that comes with the standard library. In older versions, I would choose one of these three:</p>
<ul>
<li><a href="https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/client.html">Jersey</a>: My top pick.</li>
<li><a href="https://github.com/googleapis/google-http-java-client">Google Http Java Client</a></li>
<li><a href="https://hc.apache.org/httpcomponents-client-ga/">Apache Http Client</a></li>
<li><a href="https://square.github.io/okhttp/"><span class="caps">OK</span> Http</a></li>
</ul>
</li>
<li>
<p><span class="caps">HTTP</span> Server Library. I had never been fully on board with any of <span class="caps">HTTP</span> <span class="caps">REST</span> web frameworks in the past. As of the summer of 2019, my opinion has not changed. I would like to see a lightweight framework that are easy to get started, logically compact, and easy to upgrade.</p>
<ul>
<li>Easy to get started. <a href="https://github.com/spring-projects/spring-boot">Spring Boot</a> and <a href="https://www.dropwizard.io/en/latest/getting-started.html">DropWizard</a> are good in this regard.</li>
<li>Opinionated and hardened designs on its <span class="caps">API</span> and usage.</li>
<li>A minimum set of well-chosen dependencies. The library maintainers need to be disciplined to keep the dependency graph small. Existing frameworks are hard to upgrade due to conflicting dependencies issues. </li>
<li>Make stuffs optional: Features such <span class="caps">ORM</span>, Swagger, and Metrics should be are extensions. </li>
</ul>
<p>If I have to create a lightweight <span class="caps">REST</span> <span class="caps">API</span> server, I would base on <a href="https://eclipse-ee4j.github.io/jersey.github.io/documentation/3.0.0/jaxrs-resources.html">Jersey</a>. See an <a href="https://github.com/eclipse-ee4j/jersey/blob/master/examples/helloworld/src/main/java/org/glassfish/jersey/examples/helloworld/App.java">example</a>). It is worth mentioning a few <span class="caps">REST</span> alternatives: GraphQL, <span class="caps">GRPC</span>, and Twirp. </p>
</li>
<li>
<p><a href="https://www.yourkit.com/docs/java/help/connect.jsp">Yourkit</a> is a decent profiling tool.</p>
</li>
</ul>
<p><br/></p>
<h4 id="dependency">Dependency<a class="headerlink" href="#dependency" title="Permanent link">¶</a></h4>
<p>The <a href="https://well-typed.com/blog/2008/04/the-dreaded-diamond-dependency-problem/">diamond dependency problem</a> will show up one way or the other. Regardless if it is a monorepo or multi-repo setup, dependency issues cause significant headaches and time spent on trouble shooting. The problem will show up unexpectedly when there are attempts to upgrade Java version, introduce a new computing framework, use a new build tool, upgrade old libraries, or add features to legacy applications. </p>
<p>The worst offenders are also the most popular libraries and frameworks: Guava, Jackson, Jetty, Jersey, Dropwizard, Spring, etc. Issues on libraries such Guava or Jackson are usually easy to resolve. Issues caused by Jetty and Jersey are still manageable. When it comes to Spring, it requires a healthy dosage of mental fortitude as much as debugging experiences. It speaks volume to the importance of choosing technologies with a long view.</p>
<p>The most common strategy is to specify a fixed version of the conflicting library. However, that is easier said than done. In all likely scenarios, the dependency graph is generated through walking down transitive dependencies. There are likely too many conflicting libraries to manually inspect by hand. The hard part is to identify a smallest set that works for the application in question. It is an art. </p>
<p><br/></p>
<h4 id="tooling">Tooling<a class="headerlink" href="#tooling" title="Permanent link">¶</a></h4>
<p>For dependency management, I would only consider <a href="https://ant.apache.org/ivy/m2comparison.html">Maven and Ivy</a>. Both work well enough, and most build tools will be able to work pull and push dependencies from both type of repositories. However, each build tool has a strong preference over one or the other. </p>
<ul>
<li>
<p><strong>Maven</strong>: This is by far the most popular build tool. It has been around for a long time. It is the simplest to use. It works out of the box. It is designed to work for Java projects. I would not try to fit this tool to work with any other languages.</p>
</li>
<li>
<p><strong>Gradle</strong>: It is a general purpose build tool. I do not have experiences using this for a monorepo including multiple languages. I would choose Bazel instead if that is the goal.</p>
</li>
<li>
<p><strong>Ant</strong>: It is a general purpose build tool.</p>
</li>
<li>
<p><strong>Make</strong>: Good luck! If it is a toy project with multiple languages, it is fun to use make. It would not be practical for any production system.</p>
</li>
<li>
<p><strong>Bazel</strong>: With the maturing of the Bazel rule on using Maven <a href="https://github.com/bazelbuild/rules_jvm_external">artifacts</a>, I am choosing Bazel for both small and large projects for java-only as well as monorepo supporting multiple languages. I will write a post and example on how I maintain my bazel-based playground monorepo supporting go, python, c++, java, scala, and javascript. </p>
</li>
</ul>
<p><br/></p>
<h4 id="application-setup">Application Setup<a class="headerlink" href="#application-setup" title="Permanent link">¶</a></h4>
<ul>
<li>
<p>Spring Framework: <span class="caps">NO</span>! I would avoid using Spring for dependency injection, configuration, bean life cycle, task scheduling, datasources mapping, etc.</p>
<ul>
<li>No compile time checks.</li>
<li>Misconfigurations show up at runtime. It is hard to debug. </li>
<li>A bloated library. It always causes unexpected dependency problems. It always did, and always will.</li>
<li>Hard to test components</li>
<li>Too flexible and hard to enforce usage guidelines. Invariably, bad patterns will show up and it will be a losing battle maintain sanity.</li>
</ul>
</li>
<li>
<p>Dependency Injection: My current vote is a no. I would architect my applications to be sufficiently small and wire them by hand. If I have to use one because for so many other reasons, the application has to be monolithically large and complex, I would go with Dagger. The <a href="https://stackoverflow.com/questions/39688830/why-use-develop-guice-when-you-have-spring-and-dagger">history</a> of major dependency injection frameworks in Java is a starting point to learn more about Spring, Guice, and Dagger.</p>
</li>
<li>
<p>Configuration: There are three common ways to store configurations: command line args, config files, and environment variables. There are good reasons to use any of the three. A design principle like <a href="https://12factor.net/">12 factor</a> might or might not work well for your <span class="caps">CI</span>/<span class="caps">CD</span> and production environments. But in terms of simplicity of user experiences, I would say using only command line args is the simplest, followed by config files, and then environment variables. I prefer staying with the simplest model until it is necessary to add complexity.</p>
</li>
</ul>
<p><br/></p>
<h4 id="style">Style<a class="headerlink" href="#style" title="Permanent link">¶</a></h4>
<p>I prefer to choose a style and setup a formatter. Debating how to line break while reviewing a feature release is counter-productive, but I totally get it that there are indents and long lines could lead to compulsively typing “ugly”. I would pick <a href="https://google.github.io/styleguide/javaguide.html">Google java style guide</a> and integrates the <a href="https://github.com/google/google-java-format">formatter</a> into the build tool. The formatter could be run automatically. <a href="https://blog.golang.org/gofmt">go-fmt</a> says it the best. Formatted code is:</p>
<ul>
<li>easier to <strong>write</strong>: never worry about minor formatting concerns while hacking away,</li>
<li>easier to <strong>read</strong>: when all code looks the same you need not mentally convert others’ formatting style into something you can understand.</li>
<li>easier to <strong>maintain</strong>: mechanical changes to the source don’t cause unrelated changes to the file’s formatting; diffs show only the real changes.</li>
<li><strong>uncontroversial</strong>: never have a debate about spacing or brace position ever again!</li>
</ul>
<p><br/></p>
<h4 id="fun-reads-in-java">Fun reads in Java<a class="headerlink" href="#fun-reads-in-java" title="Permanent link">¶</a></h4>
<ul>
<li><a href='#zerocopy2016' id='ref-zerocopy2016-1'>
zer16
</a>, <a href='#nagaraja2008' id='ref-nagaraja2008-1'>
PN08
</a></li>
<li><a href='#kreps2013' id='ref-kreps2013-1'>
Jcs13
</a></li>
<li><a href='#sor2013' id='ref-sor2013-1'>
Sor13
</a>, <a href="https://stackoverflow.com/questions/38597965/difference-between-resident-set-size-rss-and-java-total-committed-memory-nmt">Java memory usage in docker</a></li>
</ul>
<div id="citations">
<hr>
<h3>Citations</h3>
<ol class="references">
<li id="bloch2018">
<span class="reference-text">Bloch, Joshua.
<em>Effective Java Third Edition</em>.
Pearson Education Inc., 2018.</span>
<a class="cite-backref" href="#ref-bloch2018-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
<a class="cite-backref" href="#ref-bloch2018-2"
title="Jump back to reference 2">
<sup>
<i>
<b>
2
</b>
</i>
</sup>
</a>
</li>
<li id="checkedexception2014">
<span class="reference-text">Checked exceptions: java’s biggest mistake.
2014.
URL: <a href="http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/">http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/</a>.</span>
<a class="cite-backref" href="#ref-checkedexception2014-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="thompson2011">
<span class="reference-text">Thompson, Martin.
Java lock implementations.
2011.
URL: <a href="https://mechanical-sympathy.blogspot.com/2011/11/java-lock-implementations.html">https://mechanical-sympathy.blogspot.com/2011/11/java-lock-implementations.html</a>.</span>
<a class="cite-backref" href="#ref-thompson2011-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="thompson2011_2">
<span class="reference-text">Biased locking, osr, and benchmarking fun.
2011.
URL: <a href="https://mechanical-sympathy.blogspot.com/2011/11/biased-locking-osr-and-benchmarking-fun.html">https://mechanical-sympathy.blogspot.com/2011/11/biased-locking-osr-and-benchmarking-fun.html</a>.</span>
<a class="cite-backref" href="#ref-thompson2011_2-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="dice2006">
<span class="reference-text">Dice, Dave.
Biased locking in hotspot.
2006.
URL: <a href="http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/">http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/</a>.</span>
<a class="cite-backref" href="#ref-dice2006-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="goetz2004">
<span class="reference-text">Goetz, Brian.
Going atomic.
2004.
URL: <a href="https://blogs.oracle.com/dave/biased-locking-in-hotspot">https://blogs.oracle.com/dave/biased-locking-in-hotspot</a>.</span>
<a class="cite-backref" href="#ref-goetz2004-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="atomicinteger2014">
<span class="reference-text">When is atomicinteger preferrable over synchronized?
2014.
URL: <a href="https://stackoverflow.com/questions/11670687/when-is-atomicinteger-preferrable-over-synchronized">https://stackoverflow.com/questions/11670687/when-is-atomicinteger-preferrable-over-synchronized</a>.</span>
<a class="cite-backref" href="#ref-atomicinteger2014-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="goetz2006">
<span class="reference-text">Goetz, Brian.
<em>Java Concurrency in Practice</em>.
Pearson Education Inc., 2006.</span>
<a class="cite-backref" href="#ref-goetz2006-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="zerocopy2016">
<span class="reference-text">It's all about buffers: zero-copy, mmap and java nio.
2016.
URL: <a href="https://xunnanxu.github.io/2016/09/10/It-s-all-about-buffers-zero-copy-mmap-and-Java-NIO/">https://xunnanxu.github.io/2016/09/10/It-s-all-about-buffers-zero-copy-mmap-and-Java-NIO/</a>.</span>
<a class="cite-backref" href="#ref-zerocopy2016-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="nagaraja2008">
<span class="reference-text">Palaniappan, Sathish and Nagaraja, Pramod.
Efficient data transfer through zero copy.
2008.
URL: <a href="https://developer.ibm.com/languages/java/articles/j-zerocopy/">https://developer.ibm.com/languages/java/articles/j-zerocopy/</a>.</span>
<a class="cite-backref" href="#ref-nagaraja2008-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="kreps2013">
<span class="reference-text">Jcs.
<em>The Log: What every software engineer should know about real-time data's unifying abstraction</em>.
2013.
URL: <a href="https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying">https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying</a>.</span>
<a class="cite-backref" href="#ref-kreps2013-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
<li id="sor2013">
<span class="reference-text">Šor, Vladimir.
It's all about buffers: zero-copy, mmap and java nio.
2013.
URL: <a href="https://plumbr.io/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx">https://plumbr.io/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx</a>.</span>
<a class="cite-backref" href="#ref-sor2013-1"
title="Jump back to reference 1">
<sup>
<i>
<b>
1
</b>
</i>
</sup>
</a>
</li>
</ol>
</div>
<hr/>
<script src="https://utteranc.es/client.js"
repo="jinfwhuang/jinfwhuang.github.io"
issue-term="pathname"
label="user-comments"
theme="github-light"
crossorigin="anonymous"
async>
</script>
<hr/>
<aside>
<nav>
<ul class="articles-timeline">
<li class="previous-article">« <a href="/2019-04-13-quote-of-the-month" title="Previous: Quote of the Month">Quote of the Month</a></li>
<li class="next-article"><a href="/2020-02-01-data-streaming" title="Next: Streaming Data Platform">Streaming Data Platform</a> »</li>
</ul>
</nav>
</aside>
</div>
<section id="article-sidebar" class="span2">
<h4>Published</h4>
<time itemprop="dateCreated" datetime="2019-06-01T00:00:00-07:00">Sat 01 June 2019</time>
<!-- <h4>Category</h4>
<a class="category-link" href="/categories#misc-ref">misc</a>
-->
<h4>Tags</h4>
<ul class="list-of-tags tags-in-article">
<li><a href="/tags#java-ref">java
<span class="superscript">1</span>
</a></li>
</ul>
<h4>Contact</h4>
<div id="sidebar-social-link">
<a href="https://twitter.com/jinfwhuang" title="Twiiter" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Twitter" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#1da1f3"/><path fill="#fff" d="M437 152a72 72 0 0 1-40 12 72 72 0 0 0 32-40 72 72 0 0 1-45 17 72 72 0 0 0-122 65 200 200 0 0 1-145-74 72 72 0 0 0 22 94 72 72 0 0 1-32-7 72 72 0 0 0 56 69 72 72 0 0 1-32 1 72 72 0 0 0 67 50 200 200 0 0 1-105 29 200 200 0 0 0 309-179 200 200 0 0 0 35-37"/></svg>
</a>
<a href="https://www.linkedin.com/in/jinfwhuang" title="LinkedIn" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="LinkedIn" role="img" viewBox="0 0 512 512" fill="#fff"><rect width="512" height="512" rx="15%" fill="#0077b5"/><circle cx="142" cy="138" r="37"/><path stroke="#fff" stroke-width="66" d="M244 194v198M142 194v198"/><path d="M276 282c0-20 13-40 36-40 24 0 33 18 33 45v105h66V279c0-61-32-89-76-89-34 0-51 19-59 32"/></svg>
</a>
</div>
</section>
</div>
</article>
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div> </div>
<div class="span1"></div>
</div>
</div>
</div>
<!-- <footer>
<div>
<span class="site-name"><span style="color:black;">Jin's Notes</span></span> - the hardest part is taking the first step
</div>
<div id="fpowered">
Powered by: <a href="http://getpelican.com/" title="Pelican Home Page" target="_blank" rel="nofollow noopener noreferrer">Pelican</a>
Theme: <a href="https://elegant.oncrashreboot.com/" title="Theme Elegant Home Page" target="_blank" rel="nofollow noopener noreferrer">Elegant</a>
</div>
</footer>-->
<script src="//code.jquery.com/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="/theme/js/elegant.prod.9e9d5ce754.js"></script>
<script>
function validateForm(query)
{
return (query.length > 0);
}
</script>
<script>
(function () {
if (window.location.hash.match(/^#comment-\d+$/)) {
$('#comment_thread').collapse('show');
}
})();
window.onhashchange=function(){
if (window.location.hash.match(/^#comment-\d+$/))
window.location.reload(true);
}
$('#comment_thread').on('shown', function () {
var link = document.getElementById('comment-accordion-toggle');
var old_innerHTML = link.innerHTML;
$(link).fadeOut(200, function() {
$(this).text('Click here to hide comments').fadeIn(200);
});
$('#comment_thread').on('hidden', function () {
$(link).fadeOut(200, function() {
$(this).text(old_innerHTML).fadeIn(200);
});
})
})
</script>
</body>
<!-- Theme: Elegant built for Pelican
License : MIT -->
</html>