Digital Library

Java程序性能优化实战 (葛一鸣)(Z-Library)

葛一鸣

Java程序性能优化实战 (葛一鸣)(Z-Library)

Author 葛一鸣

java
Language English

No Description

Format EPUB
Size 5.8 MB
172
Views
0
Downloads
0.00
Total Donations

AI Guide

AI Reading Assistant

Whole-book reading guide from stratified index samples; jump to passages in the text

Full assistant
AI guide
# Java程序性能优化实战 — Reading Guide 【One-Line Pitch】 A practical handbook for Java developers who want to systematically diagnose and eliminate performance bottlenecks—covering design patterns, JVM internals, data structures, and concurrency—with concrete code examples and benchmark data. Read this if you are a working Java engineer facing slow startup, memory leaks, or high-latency issues and want a structured approach to optimization rather than random tweaks. 【Book Arc】 - **Opening (~0%–9%)**: Introduces performance fundamentals—what performance means, key metrics, the bucket principle (system performance is limited by its worst component), and Amdahl's Law (parallel speedup is bounded by the serial fraction). It then maps the optimization landscape: code, architecture, JVM, database, and OS levels, plus general tuning steps and precautions. - **Early (~9%–25%)**: Dives into performance-oriented design patterns, with heavy emphasis on the proxy pattern for lazy loading. Walks through static proxies, JDK dynamic proxies, CGLIB, and Javassist (both factory-based and bytecode-based), complete with creation-time and method-call benchmarks. Also covers business proxy patterns that encapsulate remote-call workflows to reduce network pressure. - **Early (~25%–34%)**: Moves to performance components—buffering, caching, and pooling. Uses C3P0 as a concrete database connection pool example, showing how pooled connections are actually proxies wrapping real connections, and how closing a pooled connection returns it to the pool rather than closing the underlying resource. Introduces object pooling for heavyweight objects, including Apache Commons Pool with soft-reference variants. - **Middle (~38%–47%)**: Shifts to JVM-level memory issues, starting with a classic Java 6 `substring()` memory leak caused by shared char arrays with offset/count. Shows how the space-for-time strategy in the package-private String constructor can retain huge backing arrays, and contrasts with the Java 7 fix that copies only the needed range. Also begins the List data structure comparison (ArrayList vs. Vector vs. LinkedList). - **Middle (~47%–53%)**: Continues the data structure deep-dive, comparing ArrayList's array-copy behavior on insertion versus LinkedList's linked-node structure. Demonstrates that inserting at the front of an ArrayList triggers expensive `System.arraycopy` operations, while LinkedList handles arbitrary-position insertion uniformly. The excerpts end mid-benchmark, so later chapters presumably cover additional collections, concurrency utilities, and JVM tuning—though those sections are not fully represented in this sample. 【Key Takeaways】 - **Performance tuning is a layered discipline** (Early): The bucket principle and Amdahl's Law frame optimization as a system-wide effort—fix the worst component first, and remember that adding CPUs only helps if parallelism increases. This gives you a mental model for prioritizing work across code, JVM, database, and OS. - **Proxy patterns enable lazy loading with measurable trade-offs** (Early): Using a proxy to defer expensive initialization (e.g., database connections) can dramatically speed up system startup. Benchmark data shows JDK dynamic proxies create fastest (native `defineClass`) but CGLIB and Javassist bytecode proxies win on method-call performance—which matters more in practice since calls vastly outnumber creations. - **Dynamic proxy choice depends on your constraints** (Early): JDK proxies require the target to implement an interface; CGLIB and Javassist do not. Javassist's factory-based proxy performed worst in method-call benchmarks, so prefer CGLIB or Javassist bytecode generation unless you have a specific reason otherwise. Hibernate's lazy loading is a real-world example—it generates CGLIB subclasses that intercept getters to defer SQL until data is actually accessed. - **Connection pooling is proxy-based reuse** (Early): C3P0 returns `NewProxyConnection` wrappers around real JDBC connections; closing the proxy returns the connection to the pool rather than closing it. Verifying that two consecutive `getConnection()` calls yield the same underlying connection confirms reuse. This pattern reduces connection creation overhead and is essential for database-heavy applications. - **Pool only heavyweight objects** (Early–Middle): Object pooling pays off only when object creation is expensive and objects are frequently used. For lightweight objects, pool maintenance costs can exceed the savings. The Apache Commons Pool example shows three threads sharing just three pooled objects across hundreds of borrow/return cycles, with `destroyObject()` cleaning up on pool close. - **Java 6 `substring()` had a real memory leak** (Middle): The package-private String constructor shared the original char array with offset/count, so a tiny substring from a huge string retained the entire backing array. This caused repeated Full GCs and eventual OOM in the `HugeStr` example. Java 7 fixed it by copying only the needed range via `Arrays.copyOfRange`—a cautionary tale about space-for-time trade-offs. - **ArrayList vs. LinkedList is a positional performance story** (Middle): ArrayList appends are cheap (just `ensureCapacity` + array write), but inserting at the front triggers full array copies via `System.arraycopy`, with cost growing as the insertion index moves earlier. LinkedList handles insertions uniformly regardless of position, making it the better choice for frequent front-of-list operations—though at the cost of higher per-element memory overhead. 【Reading Tips】 - **Skim the opening theory chapter** (~0%–9%): The bucket principle and Amdahl's Law are worth internalizing, but the rest is standard performance-introduction material. Move quickly to the pattern chapters where the practical value starts. - **Deep-read the proxy pattern section** (~9%–25%): This is the richest part of the sample. Study the four proxy implementations side by side, run the benchmark code yourself, and note the trade-off table (creation speed vs. call speed vs. interface requirement). The Hibernate example is a great case study for how frameworks apply these ideas. - **Pay attention to the benchmark methodology** (Early): The book consistently measures both creation time and method-call time, and explains why call time matters more (repeated calls vs. one-time creation). Adopt this mindset in your own optimization work—always measure the hot path, not just the setup. - **Treat the memory-leak section as a debugging lesson** (Middle): The `substring()` example shows how to diagnose a leak via GC logs (repeated Full GCs that recover memory but never stabilize) and how to fix it by removing strong references. Even though the Java 6 bug is historical, the diagnostic pattern is timeless. - **Use the List comparison as a decision framework** (Middle): When choosing between ArrayList and LinkedList, think about your access pattern: random access and tail-appends favor ArrayList; frequent front/middle insertions favor LinkedList. The book's code-level analysis (array copy vs. node linking) gives you the "why" behind the rule of thumb. 【Coverage Limits】 This guide is based on a 22-chunk sample covering roughly the first half of the book (through ~53%). Later sections on JVM tuning, concurrency utilities, and advanced optimization techniques are not represented in the excerpts and are therefore not covered here.

Passage locations

Excerpt 1
当迅速的。 在系统启动时,将消耗资源最多的方法都使用代理模式分离,这样就可以加快系统的启动速度,从而减少用户的等待时间。而在用户真正做查询操作时,再由代理类单独去加载真实的数据库查询类,从而完成用户的请求。这个过程就是使用代理模式实现了延迟加载。 注意: 代理模式可以用于多种场合,如用于远程调用的网络代理,以及考...
View in text
Excerpt 2
} System.out.println(u.getName()); } 以上代码在执行load(User.class.1)后,首先输出了User的类名、父类名以及User实现的接口,最后输出调用User的getName()方法,取得数据库中的数据。这段程序的输出结果如下(本例中使用的是Hibernate 3.2...
View in text
Excerpt 3
对象(标志位为空闲)并返回,而且将标志位设置为使用中,当对象使用完成后,将标志位设置为空闲,并归还对象池,等待下次使用。 在实际开发中,开发人员完全不必自行开发对象池,因为在Apache中已经提供了一个Jakarta Commons Pool对象池组件,可以直接使用。 Jakarta Commons Pool定义...
View in text
Excerpt 4
题只存在于Java 6及之前的版本中,在之后的Java版本中由于String的实现有了变化,因此不再存在内存泄漏的问题。以下就是Java 7中String的一个构造函数的实现: 01 public String(char value[], int offset, int count) { 02 if (offse...
View in text

Support Author

0.00
Total Amount (¥)
0
Donation Count
Please enter an amount Minimum ¥1

You will be redirected to Alipay to complete payment, then return here.

Recommended for You

Loading recommended books...
Failed to load, please try again later
Back to List