ï»??xml version="1.0" encoding="utf-8" standalone="yes"?> Level: Intermediate Amit Mathur (amitmat@us.ibm.com), Senior Technical Consultant and Solutions Enablement Manager, IBM 17 May 2004 This is the conclusion of the 5-part series on Java Performance.The first article in the series laid the foundation for performance tuning, and parts 2, 3 and 4 looked at various bottlenecks that can affect a system's scalability and throughput. This article covers two important topics that were not covered previously, along with providing case studies and references. A frequently asked question (FAQ) is about translating Sun-specific command-line switches to IBM-specific switches. Also, any serious performance tuning exercise, like benchmarks, cannot ignore system-wide tuning. We touch upon these topics briefly in the next section. This is followed by a few case studies that attempt to illustrate how the tools and tips described in the series are applied to solve problems in the field. The emphasis is on understanding and learning how to use the tools and techniques mentioned in the series. The article, and the series, concludes with a recap of useful references. Other Important Considerations This section talks about translating Sun Java configuration to IBM Java configuration, and System-wide tuning for AIX applications. The scope of both of these topics is quite vast, so we only touch them briefly. If you have an application that has been tuned for Sun Java, and you are attempting to migrate your application to AIX (or, for that matter, any platform running IBM Java), you may already have done the hard work. Understanding the application characteristics is half the battle. You can use the characteristics-based tuning tips explained in Part 2 and Part 3 based on the understanding obtained by the tuning exercise with Sun Java. However, we frequently receive queries about how to translate specific Sun Java command-line switches to equivalent IBM Java command-line switches. These switches almost always correspond to Garbage Collection, as a well-tuned GC is essential to any Java-based application's performance. A mapping between Sun and IBM switches is difficult because of the difference in JVM architecture. The IBM Java does not contain a Generational Garbage Collector, and does not understand any command-line switches that start with The table below attempts to translate Sun Java GC command-line switches to equivalent IBM switches. This mapping is based on the functionality of Sun switches as described in the Sun-specific article "Tuning Garbage Collection with the 1.4.2 Java Virtual Machine". You should attempt to use this table only for the very specific purpose of locating an equivalent (or close) switch for IBM Java. This is not meant to replace the tuning exercise, as even heap size requirements can be quite different. For general GC tuning tips with IBM Java, as well as for information on these and other GC switches for IBM Java, please refer to Fine-tuning Java garbage collection performance. The creation of this table did not involve any performance-related testing, but was based entirely on the documented use of the Sun switches in the reference quoted above. As the above table demonstrates, translating the switches in most cases will involve simply discarding the Sun switches for IBM platforms. This makes the GC tuning exercise for IBM Java quite painless, while still providing superior performance. Using AIX tools like But for most multi-tiered applications and especially benchmarks, system-wide tuning is unavoidable. There are several excellent resources available for AIX performance tuning that you can consider. To get an idea of the kind of tuning normally required, you can look at actual published benchmarks. If you look at a recent SpecJBB 2000 result for IBM Java on AIX, say http://www.spec.org/osg/jbb2000/results/res2003q3/jbb2000-20030624-00194.html, the OS tunings are mentioned below:
Warning: These settings must not be applied without carefully understanding the consequences, as an improper use of these settings can actually worsen the system performance. So what do the above settings do? Referring to AIX documentation, you can quickly get a better understanding of what each of these settings is doing. Let us examine each of these in turn. The The The The Finally, the So you can see that the system was switched to large pages and a fixed priority scheduler, to get record numbers with SpecJBB 2000 benchmark. Can you use these same settings in your application? Probably not, but you are now in a position to examine these commands and the scheduling policies, and experiment to suit your application characteristics. This is the next step in Performance tuning. In this section we look at a few examples, taken from actual issues handled by Java service team. These examples should give you a good idea of how to approach performance tuning, and how to use various tools to gather information that can be used for tuning exercise. Note that the cases for this section were not chosen based on how frequently the problem is encountered in the field. The emphasis is on understanding how to use the various tools and techniques discussed in the series to locate and correct performance issues. Case 1: Bad application response time The reported issue was that the Java-based application's response time was unacceptable. Using Looking at GC logs confirmed that the heap was expanding very often. This, combined with multiple allocation failures in quick succession and a very full heap, resulted in the Java application spending a lot of time just trying to locate a free chunk, not finding it, expanding the heap, and then satisfying only the current allocation request. This was fixed by specifying a larger value for The first step, using AIX tools, confirmed this to be a Java-related issue. The second step, guided by the fact that AIX tools indicated this to be a problem related with GC, could concentrate on GC logs directly. The third step used the available tuning parameters to break the unusual cycle that the application was getting into, allowing the excessive CPU time to be recovered. Another interesting scenario was raised as a performance issue, with CPU being busy most of the time. Looking at verbosegc, we could see that a GC cycle was being called a bit too frequently, resulting in the application spending most of its time doing just GC. The verbosegc traces showed that most of the GC activity was being caused due to multiple allocations of very large objects, roughly 10 MB or more in size. These were fragmenting the heap, making the GC cycles longer and thus affecting the performance. But looking at the verbosegc cycle, the customer could not say what these objects were. The easiest way to locate the culprit would have been to analyze the heapdump using HeapRoots tool. But there was another twist to the situation: the large objects were not surviving the GC cycle. So the heapdump did not show any objects of such size. This is a classic example of how profiling can be a very useful ally for locating and correcting problems in application sources. The Java Virtual Machine Profile Interface makes this problem trivial. For this particular example, we used a variation of the method described at Using JVMPI to Identify Large Memory Allocations, and were able to quickly identify the code that was doing this allocation. As the final case study for this article, we discuss a scenario that showed up looking like a simple sizing problem. An attempt was being made to scale the application to a 1000 users, and the application would run out of Java heap. Calculating the heap requirements based on the number of users, the heap size was increased from 1 GB to 1.5 GB. But this triggered OOM errors not coming because of Java heap. The Java heap would show enough free space, but the application logs would show that an OOM occurred. Using To dig further, the command-line switch For some time we tried to work around the problem by increasing the number of JNI references (if you specify a higher -Xoss value, it increases the limit in a proportional manner). But this only delayed the inevitable, and the severe Java heap fragmentation caused by the large number of pinned JNI references did not help either. A closer look at the application design revealed the true cause: an unbounded number of threads being created by the application. As the tests proceeded, the threads would wait for finalizers, and since finalizers are not predictable, there would be a large number of these threads waiting to release their JNI references. The only feasible solution in this case was to change the application code to correct these two problems. Once the application replaced the unbounded threads with a thread pool, and replaced finalizers wherever possible, the sizing work completed with flying colors. This case shows how you can sometimes end up trying to hit a moving target. An issue reported as Java heap exhaustion eventually turned out to be a design problem. Balancing the Java and Native heaps is usually a critical part of performance tuning, but in this case it was not sufficient. Having so many tools and techniques at your disposal gives you a much broader picture, allowing you to make informed decisions about what to tune. This article concludes the series. We hope you find this series a valuable guide in maximizing the performance of your Java applications on AIX. The authors thank Ashok Ambati, Rajesh Jeyapaul, Sharad Ballal, Roger Leuckie and Mark Bluemel for their input and advice on these articles. A special note of thanks goes to John Tesch, whose collection of information on AIX Java performance was a major source of inspiration to the series. Amit Mathur works in the IBM Solutions Development group, working primarily with IBM ISVs in enablement/performance of their apps on IBM eServer platforms and providing self-sufficiency to ISVs and customers by providing education and articles on developer works. Amit has more than fourteen years' experience working in Leading software support and development in C/C++, Java and databases on UNIX and Linux platforms. He holds a Bachelor of Engineering degree in Electronics and Telecommunication from India. You can reach Amit at amitmat@us.ibm.com. Sumit Chawla leads the Java Enablement initiative for IBM eServer (for AIX, Windows, and Linux platforms), assisting Independent Software Vendors for IBM Servers. Sumit has a Master of Science degree in Computer Science, with almost 10 years of experience in the IT industry, and is certified by IBM as an Application Architect. He is a frequent contributor to the developerWorks eServer zone. You can contact him at sumitc@us.ibm.com. 分代垃圾攉™›†å’Œåƈå‘垃圾收é›?/P> ¾U§åˆ«: åˆçñ” Brian Goetz, 首帙åùN—®, Quiotix Corp 2003 òq?12 æœ?01 æ—?/P>
上个æœ?/FONT>åQŒæˆ‘们分æžäº†å¼•用计数ã€å¤åˆ¶ã€æ ‡è®?æ¸…é™¤å’Œæ ‡è®?整熘q™äº›¾lå…¸çš„åžƒåœ¾æ”¶é›†æŠ€æœ¯ã€‚å…¶ä¸æ¯ä¸€¿U方法在特定æ¡äšg下都有其优点和缺ç‚V€‚例如,当有很多对象æˆäؓ垃圾æ—Óž¼Œå¤åˆ¶å¯ä»¥åšå¾—很好åQŒä½†æ˜¯æœ‰è®¸å¤šé•¿å¯¿å¯¹è±¡æ—¶å®ƒ?y¨u)®±å˜å¾—很¾pŸï¼ˆè¦åå¤å¤åˆ¶å®ƒä»¬ï¼‰ã€‚相åï¼Œæ ‡è®°-æ•´ç†å¯¹äºŽé•¿å¯¿å¯¹è±¡å¯ä»¥åšå¾—很好åQˆåªå¤åˆ¶ä¸€‹Æ¡ï¼‰åQŒä½†æ˜¯å½“有许多çŸå¯¿å¯¹è±¡æ—¶ž®±æ²¡æœ‰é‚£ä¹ˆå¥½äº†ã€‚JVM 1.2 åŠä»¥åŽç‰ˆæœ¬ä‹É用的技术称ä¸?分代垃圾攉™›†åQˆgenerational garbage collectionåQ?/I>,它结åˆäº†˜q™ä¸¤¿U技术以¾l“åˆäºŒè€…的长处åQŒç»“果就是对象分é…开销éžå¸¸ž®ã€? 在ä“Q何一个应用程åºå †ä¸ï¼Œä¸€äº›å¯¹è±¡åœ¨åˆ›å¾åŽå¾ˆå¿«å°±æˆäؓ垃圾åQŒå¦ä¸€äº›åˆ™åœ¨ç¨‹åºçš„æ•´ä¸ª˜qè¡ŒæœŸé—´ä¸€ç›´ä¿æŒç”Ÿå˜ã€‚ç»éªŒåˆ†æžè¡¨æ˜Žï¼Œå¯¹äºŽå¤§å¤šæ•°é¢å‘对象的è¯è¨€åQŒåŒ…æ‹?Java è¯è¨€åQŒç»å¤§å¤šæ•°å¯¹è±¡â€•―å¯ä»¥å¤šè¾?98%åQˆè¿™å–决于æ?zh¨¨n)¨å¯¹å¹´è½Õd¯¹è±¡çš„è¡¡é‡æ ‡å‡†åQ‰æ˜¯åœ¨å¹´è½Èš„æ—¶å€™æ»äº¡çš„。å¯ä»¥ç”¨æ—‰™’Ÿ¿U’æ•°ã€å¯¹è±¡åˆ†é…以åŽï¿½hå†…å˜½Ž¡ç†åç³»¾lŸåˆ†é…çš„æ€Õd—节或者对象分é…厾l历的垃圾收集的‹Æ¡æ•°æ¥è®¡½Ž—å¯¹è±¡çš„å¯¿å‘½ã€‚ä½†æ˜¯ä¸½Ž¡æ?zh¨¨n)¨å¦‚何计é‡åQŒåˆ†æžè¡¨æ˜Žäº†åŒä¸€ä»¶äº‹â€•―大多数对象是在òq´è½»çš„æ—¶å€™æ»äº¡çš„。大多数对象在年è½ÀL—¶æÖMº¡˜q™ä¸€äº‹å®žå¯¹äºŽæ”‰™›†å™¨çš„选择很有æ„义。特别是åQŒå½“大多数对象在òq´è½»æ—¶æ»äº¡æ—¶åQŒå¤åˆ¶æ”¶é›†å™¨å¯ä»¥æ‰§è¡Œå¾—相当好åQŒå› 为å¤åˆ¶æ”¶é›†å™¨å®Œå…¨ä¸è®¿é—®æ»äº¡çš„对象åQŒå®ƒä»¬åªæ˜¯å°†‹zÈš„对象å¤åˆ¶åˆ°å¦ä¸€ä¸ªå †åŒºåŸŸä¸ï¼Œç„¶åŽä¸€‹Æ¡æ€§æ”¶å›žæ‰€æœ‰çš„剩余½Iºé—´ã€?/P>
那些¾l历˜q‡ç¬¬ä¸€‹Æ¡åžƒåœ¾æ”¶é›†åŽä»èƒ½ç”Ÿå˜çš„对象,很大部分会æˆä¸ºé•¿å¯¿çš„æˆ–è€…æ°¸ä¹…çš„å¯¹è±¡ã€‚æ ¹æ®çŸå¯¿å¯¹è±¡å’Œé•¿å¯¿å¯¹è±¡çš„æØœåˆæ¯”例,ä¸åŒåžƒåœ¾æ”‰™›†½{–略的性能会有éžå¸¸å¤§çš„差别。当大多数对象在òq´è½»æ—¶æ»äº¡æ—¶åQŒå¤åˆ¶æ”¶é›†å™¨å¯ä»¥å·¥ä½œå¾—å¾ˆå¥½ï¼Œå› äØ“òq´è½»æ—¶æ»äº¡çš„对象永远ä¸éœ€è¦å¤åˆ¶ã€‚丘q‡ï¼Œå¤åˆ¶æ”‰™›†å™¨å¤„ç†é•¿å¯¿å¯¹è±¡å´å¾ˆç³Ÿ¾p•,它è¦ä»Žä¸€ä¸ªåнIºé—´å‘å¦ä¸€ä¸ªåнIºé—´å夿¥å›žå¤åˆ¶˜q™äº›å¯¹è±¡ã€‚相åï¼Œæ ‡è®°-æ•´ç†æ”‰™›†å™¨å¯¹äºŽé•¿å¯¿å¯¹è±¡å¯ä»¥å·¥ä½œå¾—很好åQŒå› 为长寿对象趋å‘äºŽæ²‰åœ¨å †çš„åº•éƒ¨åQŒä»Žè€Œä¸ç”¨å†å¤åˆ¶ã€‚丘q‡ï¼Œæ ‡è®°-æ¸…é™¤å’Œæ ‡è®?ç†æ•´æ”‰™›†å™¨è¦åšå¾ˆå¤šé¢å¤–çš„åˆ†æžæÖMº¡å¯¹è±¡çš„å·¥ä½œï¼Œå› äØ“åœ¨æ¸…é™¤é˜¶ŒDµå®ƒä»¬å¿…™åÕdˆ†æžå †ä¸çš„æ¯ä¸€ä¸ªå¯¹è±¡ã€?/P> 分代攉™›†å™?generializational collector)ž®†å †åˆ†äؓ多个代。在òq´è½»çš„代ä¸åˆ›å»ºå¯¹è±¡ï¼Œæ»¡èƒöæŸäº›æå‡æ ‡å‡†çš„对象,如ç»åŽ†äº†ç‰¹å®š‹Æ¡æ•°åžƒåœ¾æ”‰™›†çš„对象,ž®†è¢«æå‡åˆîC¸‹ä¸€æ›´è€çš„代。分代收集器对ä¸åŒçš„代å¯ä»¥è‡ªç”׃‹É用ä¸åŒçš„æ”‰™›†½{–ç•¥åQŒå¯¹å„代分别˜q›è¡Œåžƒåœ¾æ”‰™›†ã€?/P>
分代攉™›†çš„一个优ç‚ÒŽ(gu¨©)˜¯å®ƒä¸åŒæ—¶æ”‰™›†æ‰€æœ‰çš„ä»£ï¼Œå› æ¤å¯ä»¥ä½¿åžƒåœ¾æ”¶é›†æš‚åœæ›´çŸã€‚当分é…器ä¸èƒ½æ»¡‘›_ˆ†é…请求时åQŒå®ƒé¦–先触å‘一ä¸?ž®çš„æ”‰™›†åQˆminor collectionåQ?/I>åQŒå®ƒåªæ”¶é›†æœ€òq´è½»çš„ä»£ã€‚å› ä¸ºå¹´è½ÖM»£ä¸çš„è®¸å¤šå¯¹è±¡å·²ç»æÖMº¡åQŒå¤åˆ¶æ”¶é›†å™¨å®Œå…¨ä¸ç”¨åˆ†æžæÖMº¡çš„对象,所以å°çš„æ”¶é›†çš„æš‚åœå¯ä»¥ç›¸å½“çŸåƈ通常å¯ä»¥å›žæ”¶å¤§é‡çš„å †½Iºé—´ã€‚如果å°çš„æ”¶é›†é‡Šæ”¾äº†‘›_¤Ÿçš„å †½Iºé—´åQŒé‚£ä¹ˆç”¨æˆïL¨‹åºå°±å¯ä»¥ç«‹å³æ¢å¤ã€‚如果它ä¸èƒ½é‡Šæ”¾‘›_¤Ÿçš„å †½Iºé—´åQŒé‚£ä¹ˆå®ƒ?y¨u)®Þq‘ô¾l收集上一代,直到回收了èƒö够的内å˜ã€‚(在垃圾收集器˜q›è¡Œäº†å…¨éƒ¨æ”¶é›†ä»¥åŽä»ä¸èƒ½å›žæ”¶‘›_¤Ÿçš„å†…å˜æ—¶åQŒå®ƒ?y¨u)®†æ‰©å±•å †æˆ–è€…æŠ›å‡? 跟踪垃圾攉™›†å™¨ï¼Œå¦‚å¤åˆ¶ã€æ ‡è®?æ¸…é™¤å’Œæ ‡è®?整熽{‰åžƒåœ¾æ”¶é›†å™¨,éƒ½æ˜¯ä»Žæ ¹é›†ï¼ˆroot setåQ‰å¼€å§‹æ‰«æï¼Œé历对象间的引用åQŒç›´åˆ°è®¿é—®äº†æ‰€æœ‰æ´»çš„对象ã€?/P>
分代跟踪攉™›†å™¨ä»Žæ šw›†å¼€å§‹ï¼Œä½†æ˜¯òq¶ä¸éåŽ†æŒ‡å‘æ›´è€ä¸€ä»£ä¸å¯¹è±¡çš„引用,˜q™å‡ž®‘了è¦è·Ÿítªçš„对象囄¡š„大å°ã€‚但是这也带æ¥ä¸€ä¸ªé—®é¢˜â€•―如果更è€ä¸€ä»£ä¸çš„对象引用一个ä¸èƒ½é€šè¿‡ä»Žæ ¹å¼€å§‹çš„æ‰€æœ‰å…¶ä»–引用链到达的更òq´è½»çš„对象该怎么办? ä¸ÞZº†è§£å†³˜q™ä¸ªé—®é¢˜åQŒåˆ†ä»£æ”¶é›†å™¨å¿…须昑ּ地跟ítªä»Žè€å¯¹è±¡åˆ°òq´è½»å¯¹è±¡çš„å¼•ç”¨åÆˆž®†è¿™äº›è€åˆ°òq´è½»çš„å¼•ç”¨åŠ å…¥åˆ°ž®çš„æ”‰™›†çš„æ ¹é›†ä¸ã€‚有两ç§åˆ›å¾ä»Žè€å¯¹è±¡åˆ°òq´è½»å¯¹è±¡çš„引用的æ–ÒŽ(gu¨©)³•。è¦ä¹ˆæ˜¯ž®†è€å¯¹è±¡ä¸åŒ…å«çš„å¼•ç”¨ä¿®æ”¹äØ“æŒ‡å‘òq´è½»å¯¹è±¡åQŒè¦ä¹ˆæ˜¯ž®†å¼•用其他年è½Õd¯¹è±¡çš„òq´è½»å¯¹è±¡æå‡ä¸ºæ›´è€çš„一代ã€?/P>
ä¸ç®¡ä¸€ä¸ªè€åˆ°òq´è½»çš„引用是通过æå‡˜q˜æ˜¯æŒ‡é’ˆä¿®æ”¹åˆ›å¾çš„,垃圾攉™›†å™¨åœ¨˜q›è¡Œž®çš„æ”‰™›†æ—‰™œ€è¦æœ‰å…¨éƒ¨è€åˆ°òq´è½»çš„引用。åšåˆ°è¿™ä¸€ç‚¹çš„一¿U方法是跟踪è€çš„代,但是˜q™æ˜¾ç„¶æœ‰å¾ˆå¤§çš„开销。更好的一¿U方法是¾U¿æ€§æ‰«æè€çš„代以查找对年è½Õd¯¹è±¡çš„引用。这¿U方法比跟踪更快òq¶æœ‰æ›´å¥½çš„区域性(localityåQ‰ï¼Œä½†æ˜¯ä»ç„¶æœ‰å¾ˆå¤§çš„工作é‡ã€?/P>
赋值函敎ͼˆmutatoråQ‰å’Œåžƒåœ¾æ”‰™›†å™¨å¯ä»¥å…±åŒå·¥ä½œä»¥åœ¨åˆ›å»ø™€åˆ°òq´è½»çš„引用时¾l´æŠ¤å®ƒä»¬çš„完整列表。当对象æå‡ä¸ºæ›´è€ä¸€ä»£æ—¶åQŒåžƒåœ¾æ”¶é›†å™¨å¯ä»¥è®°å½•所有由于这¿Uæå‡è€Œåˆ›å»ºçš„è€åˆ°òq´è½»çš„引用,˜q™æ ·ž®±åªéœ€è¦è·Ÿítªç”±æŒ‡é’ˆä¿®æ”¹æ‰€åˆ›å¾çš„代间引用ã€?/P>
垃圾攉™›†å™¨å¯ä»¥æœ‰å‡ ç§æ–ÒŽ(gu¨©)³•跟踪ç”׃ºŽä¿®æ”¹çŽ°æœ‰å¯¹è±¡ä¸çš„引用而äñ”生的è€åˆ°òq´è½»çš„引用。它å¯ä»¥ä½¿ç”¨åœ¨å¼•用计数收集器ä¸ç»´æŠ¤å¼•ç”¨è®¡æ•°çš„åŒæ ·æ–ÒŽ(gu¨©)³•åQˆç¼–译器å¯ä»¥ç”Ÿæˆå›´ç»•æŒ‡é’ˆèµ‹å€¼çš„é™„åŠ æŒ‡ä×oåQ‰è·Ÿítªå®ƒä»¬ï¼Œä¹Ÿå¯ä»¥åœ¨è€ä¸€ä»£å †ä¸Šä‹É用虚拟内å˜ä¿æŠ¤ä»¥æ•获å‘è€å¯¹è±¡çš„写入。å¦ä¸€¿Uå¯èƒ½æ›´æœ‰æ•ˆçš„è™šæ‹Ÿå†…å˜æ–¹æ³•是在è€ä¸€ä»£å †ä¸ä‹É用页修改è„ä½åQˆpage modification dirty bitåQ‰ï¼Œä»¥ç¡®å®šäؓ扑ֈ°åŒ…å«è€åˆ°òq´è½»æŒ‡é’ˆçš„å¯¹è±¡æ—¶è¦æ‰«æçš„å—ã€?/P>
ç”¨ä¸€ç‚¹å°æŠ€å·§ï¼Œž®±å¯ä»¥é¿å…è·Ÿítªæ¯ä¸€ä¸ªæŒ‡é’ˆä¿®æ”¹åƈ‹‚€æŸ¥å®ƒæ˜¯å¦è·¨è¶Šä»£è¾¹ç•Œçš„开销。例如,ä¸éœ€è¦è·Ÿítªé’ˆå¯ÒŽ(gu¨©)œ¬åœ°æˆ–è€…é™æ€å˜é‡çš„å˜å‚¨åQŒå› 为它们已¾læ˜¯æ šw›†çš„一部分了。也å¯ä»¥é¿å…跟踪å˜å‚¨åœ¨æŸäº›æž„é€ å‡½æ•îC¸çš„æŒ‡é’ˆï¼Œ˜q™äº›æž„é€ å‡½æ•°åªç”¨äºŽåˆå§‹åŒ–æ–°å»ºå¯¹è±¡çš„å—æ®µåQˆå³æ‰€è°?åˆå§‹åŒ–å˜å‚¨ï¼ˆinitializing storesåQ?/I>åQ‰ï¼Œå› 䨓åQˆå‡ 乎)所有对象都是分é…到òq´è½»ä»£ä¸ã€‚ä¸½Ž¡æ˜¯ä»€ä¹ˆæƒ…å†µï¼Œ˜q行库都必须¾l´æŠ¤ä¸€ä¸ªè€å¯¹è±¡åˆ°òq´è½»å¯¹è±¡çš„引用集òq¶åœ¨æ”‰™›†òq´è½»ä»£æ—¶ž®†è¿™äº›å¼•ç”¨æ·»åŠ åˆ°æ šw›†ä¸ã€? 在图 1 ä¸ï¼Œ½Žå¤´è¡¨ç¤ºå †ä¸å¯¹è±¡é—´çš„引用。红色ç®å¤´è¡¨½Cºå¿…™åÀL·»åŠ åˆ°æ šw›†ä¸ä¾›ž®çš„æ”‰™›†ä½¿ç”¨çš„è€åˆ°òq´è½»çš„引用。è“色ç®å¤´è¡¨½CÞZ»Žæ šw›†æˆ–者年è½ÖM»£åˆ°è€å¯¹è±¡çš„引用åQŒåœ¨åªæ”¶é›†å¹´è½ÖM»£æ—¶ä¸éœ€è¦è·Ÿítªå®ƒä»¬ã€?/P> Sun JDK 使用一¿Uç§°ä¸?å¡ç‰‡æ ‡è®°åQˆcard markingåQ?/I>½Ž—法的改˜q›ç®—æ³•ä»¥æ ‡è¯†å¯¹è€ä¸€ä»£å¯¹è±¡çš„å—æ®µä¸åŒ…å«çš„æŒ‡é’ˆçš„ä¿®æ”V€‚在˜q™ç§æ–ÒŽ(gu¨©)³•ä¸ï¼Œå †åˆ†ä¸ÞZ¸€¾l?å¡ç‰‡åQŒæ¯ä¸ªå¡ç‰‡ä¸€èˆ¬éƒ½ž®äºŽä¸€ä¸ªå†…å˜é¡µã€‚JVM ¾l´æŠ¤ç€ä¸€ä¸ªå¡ç‰‡æ˜ ž®„ï¼Œå¯¹åº”äºŽå †ä¸çš„æ¯ä¸€ä¸ªå¡ç‰‡éƒ½æœ‰ä¸€ä¸ªä½åQˆåœ¨æŸäº›å®žçް䏿˜¯ä¸€ä¸ªå—èŠ‚ï¼‰ã€‚æ¯‹Æ¡ä¿®æ”¹å †ä¸å¯¹è±¡ä¸çš„æŒ‡é’ˆå—ŒD‰|—¶åQŒå°±åœ¨å¡ç‰‡æ˜ ž®„ä¸è®„¡½®å¯¹åº”é‚£å¼ å¡ç‰‡çš„相应ä½ã€‚在垃圾攉™›†æ—Óž¼Œž®±å¯¹ä¸Žè€ä¸€ä»£ä¸å¡ç‰‡ç›¸å…³è”çš„æ ‡è®°ä½è¿›è¡Œæ£€æŸ¥ï¼Œå¯¹è„çš„å¡ç‰‡æ‰«æä»¥å¯ÀL‰¾å¯¹å¹´è½ÖM»£æœ‰å¼•ç”¨çš„å¯¹è±¡ã€‚ç„¶åŽæ¸…é™¤æ ‡è®îC½ã€‚å¡ç‰‡æ ‡è®°æœ‰å‡ 项开销――å¡ç‰‡æ˜ ž®„所需的é¢å¤–空间ã€å¯¹æ¯ä¸€ä¸ªæŒ‡é’ˆå˜å‚¨æ‰€åšçš„é¢å¤–工作åQŒä»¥åŠåœ¨åžƒåœ¾æ”‰™›†æ—¶åšçš„é¢å¤–工作。对æ¯ä¸€ä¸ªéžåˆå§‹åŒ–å †æŒ‡é’ˆå˜å‚¨åQŒå¡ç‰‡æ ‡è®°ç®—法å¯ä»¥åªå¢žåŠ ä¸¤åˆ°ä¸‰ä¸ªæœºå™¨æŒ‡ä×oåQŒåÆˆè¦æ±‚在å°çš„æ”¶é›†æ—¶å¯ÒŽ(gu¨©)‰€æœ‰è„å¡ç‰‡ä¸Šçš„对象˜q›è¡Œæ‰«æã€? JDK 1.4.1 默认攉™›†å™?/FONT> 在默认情况下åQŒJDK 1.4.1 ž®†å †åˆ†äؓ两部分,一个年è½Èš„代和一个è€çš„代(实际上,˜q˜æœ‰½W¬ä¸‰éƒ¨åˆ†â€•―永久空é—ß_¼Œå®ƒç”¨äºŽå˜å‚¨è£…载的¾cÕd’Œæ–ÒŽ(gu¨©)³•对象åQ‰ã€‚借助于å¤åˆ¶æ”¶é›†å™¨åQŒå¹´è½Èš„代åˆåˆ†äؓ一个创建空é—ß_¼ˆé€šå¸¸¿UîCØ“ EdenåQ‰å’Œä¸¤ä¸ªç”Ÿå˜åŠç©ºé—´ã€? è€çš„代ä‹Éç”¨æ ‡è®?æ•´ç†æ”‰™›†å™¨ã€‚对象在¾låŽ†äº†å‡ ‹Æ¡å¤åˆ¶åŽæå‡åˆ°è€çš„代。å°çš„æ”¶é›†å°†‹zÈš„对象ä»?Eden 和一个生å˜åнIºé—´å¤åˆ¶åˆ°å¦ä¸€ä¸ªç”Ÿå˜åнIºé—´åQŒåƈå¯èƒ½æå‡ä¸€äº›å¯¹è±¡åˆ°è€çš„代。大的收集(major collectionåQ‰æ—¢ä¼šæ”¶é›†å¹´è½Èš„代,也会攉™›†è€çš„代ã€? 除了默认情况下ä‹É用的å¤åˆ¶æ”‰™›†å™¨å’Œæ ‡è®°-æ•´ç†æ”‰™›†å™¨ï¼ŒJDK 1.4.1 ˜q˜åŒ…å«å…¶ä»–å››¿U垃圾收集算法,æ¯ä¸€¿U适用于ä¸åŒçš„目的。JDK 1.4.1 包å«ä¸€ä¸ªå¢žé‡æ”¶é›†å™¨åQˆè‡ª JDK 1.2 ž®±å·²¾l出çŽîCº†åQ‰å’Œä¸‰ç§åœ¨å¤šå¤„ç†å™¨ç³»¾lŸä¸˜q›è¡Œæ›´æœ‰æ•ˆæ”¶é›†çš„æ–°æ”¶é›†å™¨â€•â€•åÆˆè¡Œå¤åˆ¶æ”¶é›†å™¨ã€åƈ行清除(scavengingåQ‰æ”¶é›†å™¨å’ŒåÆˆå‘æ ‡è®?清除攉™›†å™¨ã€‚这些新攉™›†å™¨æ˜¯ä¸ÞZº†è§£å†³åœ¨å¤šå¤„ç†å™¨ç³»¾lŸä¸åžƒåœ¾æ”‰™›†å™¨æˆä¸ÞZŽ×¾~©æ€§ç“¶é¢ˆè¿™ä¸€é—®é¢˜çš„。图 2 昄¡¤ºäº†åœ¨ä»€ä¹ˆæ—¶å€™é€‰æ‹©å¤‡ç”¨æ”‰™›†é€‰é¡¹çš„æŒ‡å¯¹{€?/P> å¢žé‡æ”‰™›†é€‰é¡¹è‡?1.2 èµ·å°±æˆäØ“ JDK çš„ä¸€éƒ¨åˆ†ã€‚å¢žé‡æ”¶é›†å‡ž®‘了垃圾攉™›†æš‚åœåQŒä»¥ç‰ºç‰²åžå能力ä¸ÞZ»£ä»øP¼Œ˜q™ä‹É它åªåœ¨æ›´çŸçš„æ”‰™›†æš‚åœéžå¸¸é‡è¦æ—¶æ‰å€¼å¾—考虑åQŒå¦‚接近实时的系¾lŸã€?/P>
Train½Ž—法æ˜?JDK ç”¨äºŽå¢žé‡æ”‰™›†çš„ç®—æ³•ï¼Œå®ƒåœ¨å †ä¸è€çš„代和òq´è½»çš„代之间创å¾ä¸€ä¸ªæ–°åŒºåŸŸã€‚è¿™äº›å †åŒºåŸŸåˆ’åˆ†ä¸ºâ€œç«è½¦ï¼ˆtrainåQ‰â€ï¼Œæ¯ä¸ªç«èžRåˆåˆ†ä¸ÞZ¸€¾pÕdˆ—的“èžR厢(caråQ‰â€ã€‚æ¯ä¸ªèžR厢å¯ä»¥åˆ†åˆ«æ”¶é›†ã€‚结果,æ¯ä¸ªç«èžR车厢¾l„æˆå•独的一代,˜q™æ„味ç€ä¸ä½†è¦è·Ÿítªè€åˆ°òq´è½»çš„引用,而且˜q˜è¦è·Ÿè¸ªä»Žè€çš„ç«èžR到年è½Èš„ç«èžR以åŠè€çš„车厢到年è½Èš„è½¦åŽ¢çš„å¼•ç”¨ã€‚è¿™ä¸ø™µ‹å€¼å‡½æ•ŽÍ¼ˆmutatoråQ‰å’Œåžƒåœ¾æ”‰™›†å™¨å¸¦æ¥äº†å¤§é‡çš„é¢å¤–工作,但是å¯ä»¥å¾—到更çŸçš„æ”¶é›†æš‚åœã€? òq¶è¡Œæ”‰™›†å™¨å’Œòq¶å‘攉™›†å™?/STRONG> JDK 1.4.1 䏿–°çš„æ”¶é›†å™¨éƒ½æ˜¯ä¸ø™§£å†›_¤šå¤„ç†å™¨ç³»¾lŸä¸åžƒåœ¾æ”‰™›†å™¨çš„é—®é¢˜è€Œè®¾è®¡çš„ã€‚å› ä¸ºå¤§å¤šæ•°åžƒåœ¾æ”‰™›†½Ž—法会在一ŒD‰|—¶é—´é‡Œä½¿ç³»¾lŸåœæ¢ï¼Œå•线½E‹çš„æ”‰™›†å™¨å¾ˆå¿«ä¼šæˆäØ“ä¼¸ç¾ƒæ€§ç“¶é¢ˆï¼Œå› äØ“åœ¨åžƒåœ¾æ”¶é›†å™¨ž®†ç”¨æˆïL¨‹åºçº¿½E‹æŒ‚èµäh—¶åQŒé™¤äº†ä¸€ä¸ªå¤„ç†å™¨ä¹‹å¤–åQŒå…¶ä»–的处ç†å™¨éƒ½æ˜¯ç©ºé—²çš„。新攉™›†å™¨ä¸çš„ä¸¤ä¸ªâ€•â€•åÆˆè¡Œå¤åˆ¶æ”¶é›†å™¨å’ŒåÆˆå‘æ ‡è®?清除攉™›†å™¨â€•â€•è®¾è®¡äØ“å‡å°‘攉™›†æš‚åœæ—‰™—´ã€‚å¦ä¸€ä¸ªæ˜¯òq¶è¡Œæ¸…除攉™›†å™¨ï¼Œå®ƒæ˜¯ä¸ºåœ¨å¤§å †ä¸Šçš„æ›´é«˜åžå能力而设计的ã€?/P>
òq¶è¡Œå¤åˆ¶æ”‰™›†å™¨ç”¨ JVM 选项 有兿U算法å¯ä»¥é€‰æ‹©åQŒæ?zh¨¨n)¨å¯èƒ½ä¸çŸ¥é“è¦ä½¿ç”¨å“ªä¸€¿Uã€?å›?2æä¾›äº†ä¸€äº›æŒ‡å¯û|¼Œž®†æ”¶é›†å™¨åˆ†äØ“å•线½E‹å’Œòq¶å‘的,以åŠåˆ†äØ“çŸæš‚åœå’Œé«˜åžå能力的。åªè¦æ?zh¨¨n)¨æŽŒæ¡äº†åº”用程åºå’Œéƒ¨çÖv环境的信æ¯ï¼Œž®Þpƒö以选择åˆé€‚çš„½Ž—法。对于许多应用程åºï¼Œé»˜è®¤çš„æ”¶é›†å™¨å¯ä»¥å·¥ä½œå¾—å¾ˆå¥½â€•â€•å› æ¤å¦‚æžœæ?zh¨¨n)¨æ²¡æœ‰æ€§èƒ½é—®é¢˜åQŒé‚£ä¹ˆå°±æ²¡å¿…è¦åŠ å…¥æ›´å¤šçš„å¤æ‚性。丘q‡ï¼Œå¦‚æžœæ‚(zh¨¨n)¨çš„应用½E‹åºæ˜¯éƒ¨¾|²åœ¨å¤šå¤„ç†å™¨¾pÈ»Ÿä¸Šæˆ–者ä‹É用éžå¸¸å¤§çš„å †åQŒé‚£ä¹ˆæ”¹å˜æ”¶é›†å™¨é€‰é¡¹å¯èƒ½ä¼šæœ‰å·¨å¤§çš„æ€§èƒ½æå‡ã€? JDK 1.4.1 ˜q˜åŒ…括大é‡çš„微调垃圾攉™›†çš„选项。调整这些选项òq¶è¡¡é‡å®ƒä»¬çš„æ•ˆæžœå¯èƒ½ä¼šèбè´ÒŽ(gu¨©)‚¨å¤§é‡æ—‰™—´åQŒå› æ¤åœ¨è¯•图微调垃圾攉™›†å™¨ä¹‹å‰å…ˆå¯ÒŽ(gu¨©)‚¨çš„应用程åºè¿›è¡Œå½»åº•çš„é…ç½®åQˆprofileåQ‰å’Œä¼˜åŒ–åQŒè¿™æ äh‚¨çš„微调工作å¯èƒ½ä¼šå¾—到更好的结果ã€?/P>
微调垃圾攉™›†é¦–å…ˆè¦åšçš„æ˜¯‹‚€æŸ¥å†—é•¿çš„ GC 输出。这会ä‹Éæ‚(zh¨¨n)¨å¾—到垃圾收集æ“作的频率ã€å®šæ—¶å’ŒæŒç®‹æ—‰™—´½{‰ä¿¡æ¯ã€‚最½Ž€å•的垃圾攉™›†å¾®è°ƒ?y¨u)®±æ˜¯æ‰©å¤§æœ€å¤§å †çš„大ž®ï¼ˆ éšç€ JVM çš„å‘展,默认垃圾攉™›†å™¨å˜å¾—è¶Šæ¥è¶Šå¥½äº†ã€‚JDK 1.2 åŠä»¥åŽç‰ˆæœ¬æ‰€ä½¿ç”¨çš„分代垃圾收集器æä¾›äº†æ¯”早期 JDK æ‰€ä½¿ç”¨çš„æ ‡è®?清除-æ•´ç†æ”‰™›†å™¨å¥½å¾—多的分é…和攉™›†æ€§èƒ½ã€‚JDK 1.4.1 é€šè¿‡å¢žåŠ æ–°çš„é’ˆå¯¹å¤šå¤„ç†å™¨¾pÈ»Ÿå’Œéžå¸¸å¤§çš„å †çš„å¤š¾U¿ç¨‹æ”‰™›†é€‰é¡¹åQŒè¿›ä¸€æ¥æ”¹˜q›äº†åžƒåœ¾æ”‰™›†çš„æ•ˆçއã€?/P>
下个月,我们ž®†è®¨è®ÞZ¸€äº›æœ‰å…›_žƒåœ¾æ”¶é›†çš„æ€§èƒ½¼œžè¯åQˆhints and mythsåQ‰ï¼ŒåŒ…括对象分é…çš„çœŸå®žæˆæœ¬ã€æ˜¾å¼èµ‹½Iºçš„代äh(hu¨¢n)和好处以åŠç»“æŸï¼ˆfinalizationåQ‰çš„代äh(hu¨¢n)åQŒä»¥æ¤æ¥å®Œæˆæˆ‘们对垃圾收集的探讨ã€?/P> Brian Goetz 在过åŽ?15 òq´é—´ä¸€ç›´ä»Žäº‹ä¸“业èÊYä»¶å¼€å‘。他æ˜?Quiotix的首å¸é¡¾é—®ï¼Œè¯¥å…¬å¸æ˜¯ä¸€å®¶ä½äºŽåŠ åˆ©ç¦ž®égºšå·žæ´›æ–¯æ‹‰å›¾æ–¯åQˆLos AltosåQ‰çš„软äšgå¼€å‘和咨询公å¸åQŒä»–ä¹Ÿæ˜¯å‡ ä¸ª JCP 专家¾l„çš„æˆå‘˜ã€‚请å‚阅‹¹è¡Œçš„业界出版物ä¸?Brian å·²ç» å‘表和峞®†å‘è¡¨çš„æ–‡ç« ã€‚æ?zh¨¨n)¨å¯ä»¥é€šè¿‡ brian@quiotix.comä¸?Brian è”ç³»ã€? 如何利用 IBM Java 虚拟机检‹¹‹å’Œè§£å†³åžƒåœ¾æ”‰™›†é—®é¢˜ ¾U§åˆ«: åˆçñ” Sumit Chawla, 技术主½Ž¡ï¼ŒeServer Java Enablement, IBM 2003 òq?1 æœ?01 æ—?/P>
垃圾攉™›†å®žçްæ˜?IBM Java Virtual MachineåQˆJVMåQ‰å“‘Šæ€§èƒ½çš„关键。其他多æ•?JVM 都需è¦å¤§é‡è°ƒæ•´æ‰èƒ½æä¾›æœ€ä¼˜æ€§èƒ½åQŒè€?IBM JVM 利用其“开½Ž±å³ç”¨â€çš„默认讄¡½®åQŒåœ¨å¤šæ•°æƒ…况下都能工作得很好。但是在æŸäº›æƒ…况下,垃圾攉™›†çš„æ€§èƒ½ä¼šèŽ«å其妙地˜q…速é™ä½Žã€‚结果å¯èƒ½å¯¼è‡´æœåŠ¡å™¨æ²¡æœ‰å“应ã€å±òq•陿¢ä¸åŠ¨æˆ–è€…å®Œå…¨å¤±æ•ˆï¼Œòq¶å¸¸å¸æ€¼´æœ‰â€œå †½Iºé—´ä¸¥é‡ä¸èƒöâ€è¿™¾cÕd«¾pŠçš„æ¶ˆæ¯ã€‚幸˜qçš„æ˜¯ï¼Œå¤šæ•°æƒ…å†µä¸‹éƒ½å¾ˆå®¹æ˜“æ‰¾åˆ°åŽŸå› ï¼Œé€šå¸¸ä¹Ÿå¾ˆå®ÒŽ(gu¨©)˜“¾U æ£é”™è¯¯ã€?/P>
本文ž®†ä»‹¾lå¦‚ä½•ç¡®å®šé€ æˆæ€§èƒ½ä¸‹é™çš„æ½œåœ¨åŽŸå› ã€‚å› ä¸ºåžƒåœ¾æ”¶é›†æ˜¯ä¸€ä¸ªå¾ˆå¤§ã€å¾ˆå¤æ‚çš„è¯é¢˜ï¼Œæ‰€ä»¥æœ¬æ–‡æ˜¯åœ¨å·²¾lå‘表的一¾l„相å…Ïx–‡ç« 的基础上展开讨论åQˆè¯·å‚阅å‚考资æ–?/FONT>åQ‰ã€‚è™½ç„¶æœ¬æ–‡è®¨è®ºçš„å¤šæ•°å»ø™®®éƒ½å°† Java ½E‹åºçœ‹ä½œæ˜¯ä¸€ä¸ªé»‘ç›’ååQŒä½†ä»ç„¶æœ‰ä¸€äº›è§‚点å¯ä»¥åœ¨è®¾è®¡æˆ–ç¼–ç æ—¶˜q用åQŒä»¥é¿å…潜在的问题ã€?/P>
本文æä¾›çš„ä¿¡æ¯é€‚用于所æœ?IBM eServer òq›_°åQŒé™¤äº†å¯é‡æ–°è®„¡½®çš?JVM é…ç½®åQˆè¯·å‚阅å‚考资æ–?/FONT>åQ‰ã€‚除éžç‰¹åˆ«è¯´æ˜Žï¼Œæ–‡ä¸çš„例å都å–自˜q行在四处ç†å™?AIX 5.1 上的 Java 1.3.1 build ca131-20020706ã€?/P> JVM 在åˆå§‹åŒ–的过½E‹ä¸åˆ†é…å †ã€‚å †çš„å¤§ž®å–决于指定或者默认的最ž®å’Œæœ€å¤§å€ég»¥åŠå †çš„ä‹É用情å†üc€‚分é…å †å¯èƒ½å¯¹å¯è§†åŒ–å †æœ‰æ‰€å¸®åŠ©åQŒå¦‚å›?1 所½Cºï¼Œå…¶ä¸æ˜„¡¤ºäº?heapbaseã€?I>heaplimit å’?heaptopã€?/P> Heapbase è¡¨ç¤ºå †åº•åQŒheaptop 则表½Cºå †èƒ½å¤Ÿå¢žé•¿åˆ°çš„æœ€å¤§ç»å¯¹å€¹{€‚å·®å€û|¼ˆ å¦‚æžœæ•´ä¸ªå †çš„è‡ªç”±½Iºé—´æ¯”例低于 å½?Java ¾U¿ç¨‹è¯äh±‚å˜å‚¨æ—Óž¼Œå¦‚æžœ JVM ä¸èƒ½åˆ†é…‘›_¤Ÿçš„å˜å‚¨å—æ¥æ»¡‘Œ™¿™ä¸ªè¯·æ±‚,则å¯ä»¥è¯´å‡ºçްäº?I>分é…å¤ÞpÓ|åQˆAFåQ‰ã€‚这时候就ä¸å¯é¿å…è¦è¿›è¡Œåžƒåœ¾æ”¶é›†ã€‚垃圾收集包括收集所有“ä¸å¯è¾¾çš„(unreachableåQ‰â€å¼•用,以便é‡ç”¨å®ƒä»¬æ‰€å 用的空间。垃圾收集由è¯äh±‚分é…的线½E‹æ‰§è¡Œï¼Œæ˜¯ä¸€¿U?Stop-The-WorldåQˆSTWåQ‰æœºåˆÓž¼›æ‰§è¡Œåžƒåœ¾æ”‰™›†½Ž—法æ—Óž¼ŒJava 应用½E‹åºçš„其他所有线½E‹ï¼ˆé™¤äº†åžƒåœ¾æ”‰™›†å¸®åŠ©å™¨çº¿½E?/FONT>之外åQ‰éƒ½è¢«æŒ‚èµ—÷€?/P>
IBM 实现使用¿UîCØ“ mark-sweep-compactåQˆMSCåQ‰çš„垃圾攉™›†½Ž—法åQŒå®ƒæ˜¯æ ¹æ®ä¸‰ä¸ªä¸åŒçš„阶段命åçš„ã€?
关于 MSC ½Ž—法的细节,请å‚é˜?A >å‚考资æ–?/FONT>ã€?/P>
虽然垃圾攉™›†æœ¬èín采用 STW 机制åQŒä½†æœ€æ–°çš„ IBM JVM 版本都在多处ç†å™¨æœºå™¨ä¸Šä‹É用多个“帮助器â€çº¿½E‹ï¼Œä»¥ä¾¿å‡å°‘æ¯ä¸ªé˜¶æ®µæ‰€èŠÞp´¹çš„æ—¶é—´ã€‚å› æ¤ï¼Œåœ¨é»˜è®¤æƒ…况下åQŒJVM 1.3.0 åœ¨æ ‡è®°é˜¶ŒDµé‡‡ç”¨åƈ行模å¼ã€‚JVM 1.3.1 åœ¨æ ‡è®°å’Œæ¸…ç†é˜¶æ®µéƒ½é‡‡ç”¨åƈ行模å¼ï¼Œåœ¨æ ‡è®°é˜¶ŒDµè¿˜æ”¯æŒä¸€¿Uå¯é€‰çš„òq¶å‘模å¼åQŒå¯ä»¥ä‹É用命令行开å…? 在拥æœ? 采用òq¶å‘æ¨¡å¼æ—Óž¼ŒJVM 会å¯åŠ¨ä¸€ä¸ªåŽå°çº¿½E‹ï¼ˆä¸åˆ©äºŽåžƒåœ¾æ”¶é›†å¸®åЩ噍¾U¿ç¨‹åQ‰ï¼Œåœ¨æ‰§è¡Œåº”用程åºçº¿½E‹çš„åŒæ—¶åQŒéƒ¨åˆ†å·¥ä½œæ˜¯åœ¨åŽå°å®Œæˆçš„。åŽå°çº¿½E‹ä¼šè¯•ç€ä¸Žåº”用程åºåÆˆå‘æ‰§è¡Œï¼Œä»¥å®Œæˆåžƒåœ¾æ”¶é›†çš„æ‰€æœ‰æ“ä½œï¼Œå› æ¤åœ¨æ‰§è¡Œåžƒåœ¾æ”¶é›†æ—¶åQŒå¯ä»¥å‡ž®?STW é€ æˆçš„æš‚åœã€‚但在æŸäº›æƒ…况下åQŒåƈå‘处ç†å¯èƒ½å¯¹æ€§èƒ½é€ æˆè´Ÿé¢å½±å“åQŒç‰¹åˆ«æ˜¯å¯¹äºŽ CPU æ•æ„Ÿçš„应用程åºã€?/P>
下表按照 JVM 版本列出了垃圾收集å„个阶ŒD늚„处熾cÕdž‹ã€?/P>
å…¶ä¸åQ?
虽然也有分枽E‹åºå’Œå…¶ä»–第三方工具åQŒä½†æœ¬æ–‡ä»…讨论对 verbosegc 日志的分æžã€‚这些日志由 JVM 在指å®?-verbosegc 命ä×oè¡Œå‚æ•°æ—¶ç”ŸæˆåQŒæ˜¯ä¸€¿Uéžå¸¸å¯é 的独立于åã^å°çš„调试工具。è¦èŽ·å¾—å®Œæ•´çš?verbosegc è¯æ³•åQŒè¯·å‚阅â€?A target=new>verbosegc and command-line parametersâ€ã€?/P>
å¯ç”¨ verbosegc å¯èƒ½å¯¹åº”用程åºçš„æ€§èƒ½æœ‰ä¸€å®šåª„å“。如果这¿Uåª„å“æ˜¯æ— 法接å—的,则应该ä‹É用测试系¾lŸæ¥æ”‰™›† verbosegc 日志。æœåŠ¡å™¨åº”ç”¨½E‹åºé€šå¸¸ä¸€ç›´ä‹É verbosegc 处于‹È€‹zÈŠ¶æ€ã€‚这是监控整ä¸?JVM 是妘qè{良好的一¿U好办法åQŒåœ¨å‡ºçް OutOfMemory 错误的情况下åQŒè¿™¿Uæ–¹æ³•å…·æœ‰æ— å¯ä¼°è®¡çš„价倹{€?/P>
ä¸ÞZº†æœ‰æ•ˆåœ°åˆ†æž?verbosegc 记录åQŒå¿…™åÀLŠŠ¾_‘ÖŠ›é›†ä¸åœ¨ç›¸å…³ä¿¡æ¯ä¸ŠåQŒåƈ˜q‡æ×o掉“噪音â€ã€‚通过¾~–写脚本从很长的 verbosegc ˜q½è¸ªè®°å½•䏿å–ä¿¡æ¯åƈä¸éš¾åQŒä½†æ˜¯è¿™äº›è®°å½•çš„æ ¼å¼å¯èƒ½åQˆè€Œä¸”通常¼‹®å®žå¦‚æ¤åQ‰éšä¸åŒçš?JVM 版本而异。下é¢çš„例å用粗体或è“色å—体表示é‡è¦çš„ä¿¡æ¯ã€‚å³ä½¿è®°å½•çš„æ ¼å¼çœ‹è“væ¥ç›¸å·®å¾ˆå¤§ï¼Œä¹Ÿå¾ˆå®ÒŽ(gu¨©)˜“åœ?verbosegc æ—¥å¿—ä¸æ‰¾åˆ°è¿™äº›ä¿¡æ¯ã€?/P>
æ‚(zh¨¨n)¨åˆ·æ–°çš„了å—åQ?/STRONG> 在å°è¯•本文ä¸çš„å¾è®®ä¹‹å‰ï¼Œå¼ºçƒˆå»ø™®®æ‚(zh¨¨n)¨å‡¾U§åˆ°æœ€æ–°çš„ JVM æœåŠ¡åˆäh–°åQˆSRåQ‰ã€‚毋ơ进行新的æœåŠ¡åˆ·æ–°éƒ½ä¼šæœ‰å¾ˆå¤šä¿®æ£å’Œæ”¹˜q›ï¼Œåº”用新的æœåŠ¡åˆäh–°å¯ä»¥æé«˜ JVM 的性能和稳定性。迿UÕdˆ°æœ€æ–°çš„版本åQˆæ¯”å¦?JVM 1.4.0 æˆ?1.3.1åQŒæ ¹æ®ä‹É用的òq›_°åQ‰æä¾›äº†å¢žå¼ºçš„æ€§èƒ½ç‰ÒŽ(gu¨©)€§ã€‚一定è¦ä¸?JVM 安装所有必需çš?OS è¡¥ä¸åQˆæ¯”å¦?AIX 上的¾l´æŠ¤¾U§åˆ«åQ‰ã€‚这些信æ¯è®°å½•在éš?SDK/JRE æä¾›çš?readme æ–‡äšgä¸ã€?/P>
计算æ£ç¡®çš„å †å¤§å°å‚数很容易,但它å¯èƒ½å¯¹åº”用程åºå¯åŠ¨æ—¶é—´å’Œ˜q行时性能有很大的影å“。åˆå§‹å¤§ž®å’Œæœ€å¤§å€¼åˆ†åˆ«ç”±å‚æ•° 上述记录表明åQŒç¬¬ä¸€‹Æ¡å‘ç”?AF æ—Óž¼Œå †ä¸çš„自ç”Þq©ºé—´äØ“ 0%åQ?983128 䏿œ‰ 0 å—节å¯ç”¨åQ‰ã€‚æ¤å¤–,½W¬ä¸€‹Æ¡åžƒåœ¾æ”¶é›†ä¹‹åŽï¼Œè‡ªç”±½Iºé—´æ¯”例上å‡åˆ?34%åQŒç•¥é«˜äºŽ å¦‚æžœå †å¤ªž®ï¼Œå³ä‹É应用½E‹åºä¸ä¼šé•¿æœŸä½¿ç”¨å¾ˆå¤šå¯¹è±¡åQŒä¹Ÿä¼šé¢‘¾J地˜q›è¡Œåžƒåœ¾æ”‰™›†ã€‚å› æ¤ï¼Œè‡ªç„¶ä¼šå‡ºçŽîC‹Éç”¨å¾ˆå¤§çš„å †çš„å€‘Ö‘ã€‚ä½†æ˜¯ç”±äºŽåã^å°å’Œå…¶ä»–æ–šw¢çš„å› ç´ ï¼Œå †çš„æœ€å¤§å¤§ž®è¿˜å—物ç†å› ç´ çš„é™åˆ¶ã€‚å¦‚æžœå †è¢«åˆ†™åµï¼Œæ€§èƒ½ž®×ƒ¼šæ€¥å‰§æ¶åŒ–åQŒå› æ¤å †çš„大ž®ä¸€å®šä¸èƒ½è¶…出安装在¾pÈ»Ÿä¸Šçš„物ç†å†…å˜æ€»é‡ã€‚比如,如果 AIX 机器上有 1 GB 的内å˜ï¼Œž®×ƒ¸åº”该ä¸?Java 应用½E‹åºåˆ†é… 2 GB çš„å †ã€?/P>
å³ä‹É应用½E‹åºåœ¨æ‹¥æœ?64 GB 内å˜çš?p690 ‘…çñ”计算æœÞZ¸Š˜q行åQŒä¹Ÿä¸ä¸€å®šå°±èƒ½ä‹Éç”? 垃圾攉™›†ç”¨äº†ž®†è¿‘五秒钟,˜q˜ä¸åŒ…括压羃åQ垃圾收集周期所èŠÞp´¹çš„æ—¶é—´ç›´æŽ¥ä¸Žå †çš„大尿ˆæ£æ¯”。一æ¡å¥½çš„原则是æ ÒŽ(gu¨©)®éœ€è¦è®¾¾|®å †çš„大ž®ï¼Œè€Œä¸æ˜¯å°†å®ƒé…¾|®å¾—太大或太ž®ã€?/P>
常è§çš„一¿U性能优化技术是ž®†åˆå§‹å †å¤§å°åQ?CODE>-XmsåQ‰è®¾æˆä¸Žæœ€å¤§å †å¤§å°åQ?CODE>-XmxåQ‰ç›¸åŒã€‚å› ä¸ÞZ¸ä¼šå‡ºçŽ°å †æ‰©å±•å’Œå †æ”¶ç¾ƒåQŒæ‰€ä»¥åœ¨æŸäº›æƒ…况下,˜q™æ ·åšå¯ä»¥æ˜¾è‘—地改善性能。通常åQŒåªæœ‰éœ€è¦å¤„ç†å¤§é‡åˆ†é…请求的应用½E‹åºæ—Óž¼Œæ‰åœ¨åˆå§‹å’Œæœ€å¤§å †å¤§å°ä¹‹é—´è®„¡½®è¾ƒå¤§çš„差倹{€‚但是è¦è®îC½åQŒå¦‚果指å®? å¦ä¸€æ–šw¢åQŒä¹Ÿå¯ä»¥ä½¿ç”¨ 如果使用大å°å¯å˜çš„å †åQˆæ¯”如, é¿å…˜q™ç§å¾ªçŽ¯çš„ä¸€¿UåŠžæ³•æ˜¯å¢žåŠ å¦‚æžœè®°å½•è¡¨æ˜ŽåQŒéœ€è¦å¤š‹Æ¡æ‰©å±•æ‰èƒ½è¾¾åˆ°ç¨³å®šçš„å †å¤§ž®ï¼Œä½†å¯ä»¥æ›´æ”? 使用 verbosegc 最é‡è¦çš„一™åÒŽ(gu¨©)£€æŸ¥æ˜¯æ²¡æœ‰å‡ºçŽ°â€œmark stack overflowâ€æ¶ˆæ¯ã€‚下é¢çš„记录昄¡¤ºäº†è¿™¿U消æ¯åŠå…¶åª„å“ã€?/P>
åœ¨åžƒåœ¾æ”¶é›†çš„æ ‡è®°é˜¶æ®µåQŒå¦‚æžœå¼•ç”¨çš„ä¸ªæ•°é€ æˆ JVM å†…éƒ¨çš„â€œæ ‡è®°æ ˆâ€æº¢å‡ºï¼Œž®×ƒ¼šå¼•员q™ç§æ¶ˆæ¯ã€‚åœ¨æ ‡è®°é˜¶æ®µåQŒåžƒåœ¾æ”¶é›†å¤„ç†ä»£ç ä‹Éç”¨è¿™ä¸ªæ ˆåŽ‹å…¥æ‰€æœ‰å·²çŸ¥çš„å¼•ç”¨åQŒä»¥ä¾‰K€’å½’æ‰«ææ¯ä¸ª‹zÕdŠ¨å¼•ç”¨ã€‚æº¢å‡ºçš„åŽŸå› æ˜¯å †ä¸çš„‹zÕdŠ¨å¯¹è±¡˜q‡å¤šåQˆæˆ–者更准确地说åQŒå¯¹è±¡åµŒå¥—过深)åQŒè¿™é€šå¸¸è¡¨æ˜Žåº”用½E‹åºä»£ç å˜åœ¨¾~ºé™·ã€‚除éžèƒ½å¤Ÿé€šè¿‡å¤–部讄¡½®æŽ§åˆ¶åº”用½E‹åºä¸çš„‹zÕdŠ¨å¯¹è±¡ä¸ªæ•°åQˆæ¯”如柿Uå¯¹è±¡æ± åQ‰ï¼Œé‚£ä¹ˆéœ€è¦åœ¨åº”用½E‹åºæºä»£ç ä¸è§£å†³˜q™ä¸ªé—®é¢˜ã€‚å¾è®®ä‹É用分æžå·¥å…ïL¡®å®šæ´»åŠ¨çš„å¼•ç”¨ã€?/P>
如果ä¸èƒ½é¿å…大é‡çš„æ´»åŠ¨å¼•ç”¨ï¼Œòq¶å‘æ ‡è®°å¯èƒ½æ˜¯ä¸€¿Uå¯è¡Œçš„选择ã€?/P>
下é¢çš„记录显½CÞZº†ä¸€¿U有‘£çš„æƒ…况åQšè§£å†›_ˆ†é…失败花费了 2.78 ¿U’é’ŸåQŒå…¶ä¸è¿˜ä¸åŒ…括压¾~©æ‰€ç”¨çš„æ—‰™—´ã€?/P>
¾|ªé¼œ”R¦–是必™å»è¢«¾l“æŸæŽ‰çš„å¯¹è±¡æ•°é‡ã€‚æ— è®ºå¦‚ä½•ï¼Œä½¿ç”¨ finalizer 䏿˜¯ä¸€ä¸ªå¥½ä¸ÀL„åQŒè™½ç„¶åœ¨ç‰¹å®šçš„æƒ…况下˜q™æ˜¯ä¸å¯é¿å…的,但是应该仅仅ž®†å®ƒä½œäؓ完æˆå…¶ä»–æ–ÒŽ(gu¨©)³•ä¸èƒ½å®žçŽ°çš„æ“作的ä¸å¾—已方法。比方说åQŒæ— 论如何都è¦é¿å…在 finalizer 内部执行分é…ã€?/P>
æœ‰æ—¶å€™é—®é¢˜ä¸æ˜¯ç”±å½“æ—¶çš„å †çŠ¶æ€é€ æˆçš„ï¼Œè€Œæ˜¯å› äØ“åˆ†é…å¤ÞpÓ|é€ æˆçš„。比如: ˜q™äº›è®°å½•æ¥è‡ªä¸€ä¸ªéžå¸¸è€çš„ JVMåQˆå‡†¼‹®åœ°è¯´æ˜¯ 分é…的内å˜å—都必™åÀL˜¯˜qžç®‹çš„,而éšç€å †è¶Šæ¥è¶Šæ»¡ï¼Œæ‰‘Öˆ°è¾ƒå¤§çš„连¾lå—‘Šæ¥‘Šå›°éš¾ã€‚è¿™ä¸ä»…仅是 Java 的问题,使用 C ä¸çš„ malloc 也会é‡åˆ°˜q™ä¸ªé—®é¢˜ã€‚JVM 在压¾~©é˜¶ŒDµé€šè¿‡é‡æ–°åˆ†é…引用æ¥å‡ž®‘碎片,但其代äh(hu¨¢n)是è¦å†È»“应用½E‹åºè¾ƒé•¿çš„æ—¶é—´ã€‚上é¢çš„记录表明已ç»å®Œæˆäº†åŽ‹¾~©é˜¶ŒDµï¼Œåˆ†é…一大嗽Iºé—´çš„æ€ÀL—¶é—´è¶…˜q‡äº† 2¿U’ã€?/P>
下é¢çš„记录说明了最¾pŸç³•的一¿U情å†üc€?/P>
è¯äh±‚的是一ä¸?2 MB 的对象(2241056 bytesåQ‰ï¼Œè™½ç„¶åœ?1.2 GB çš„å †åQ?291844600åQ‰ä¸æœ?135 MB (135487112) 自由½Iºé—´åQŒä½†å´ä¸èƒ½åˆ†é…一ä¸?2 MB çš„å—。虽然进行了一切å¯èƒ½çš„æœçƒ¦åQŒèŠ±è´¹äº† 268 ¿U’,但ä»ç„¶æ²¡æœ‰æ‰¾åˆ°èƒö够大的å—。而且˜q˜å‡ºçŽîCº†¾pŸç³•çš„â€œå †½Iºé—´ä¸¥é‡ä¸èƒöâ€æ¶ˆæ¯ï¼ŒæŒ‡å‡º JVM 的内å˜ä¸‘Ÿë€?/P>
最好的办法是:如果å¯èƒ½çš„è¯åQŒæŠŠåˆ†é…è¯äh±‚分解æˆè¾ƒ?y¨u)®çš„å—ã€‚è¿™æ øP¼Œè¾ƒå¤§çš„å †½Iºé—´å¯èƒ½ä¼šè“v作用åQŒä½†å¤šæ•°æƒ…况下,˜q™æ ·åšåªæ˜¯æŽ¨˜qŸäº†é—®é¢˜å‡ºçŽ°çš„æ—¶é—´ã€?/P>
我们å†çœ‹ä¸€çœ‹ä¸Šä¾‹ä¸çš„å…¶ä¸ä¸€è¡Œï¼š 虽然æœ?177 MB 的自ç”Þq©ºé—ß_¼Œå´ä¸èƒ½åˆ†é…?2 MB çš„å—ã€‚åŽŸå› åœ¨äºŽï¼šè™½ç„¶åžƒåœ¾æ”‰™›†å‘¨æœŸå¯ä»¥åŽ‹ç¾ƒå †ä¸çš„唋zžï¼Œä½†æ˜¯å †ä¸æœ‰äº›å†…容ä¸èƒ½åœ¨åŽ‹¾~©è¿‡½E‹ä¸é‡æ–°åˆ†é…。比如,应用½E‹åºå¯èƒ½ä½¿ç”¨ JNI 分é…和引用对象或数组。这些分é…在内å˜ä¸æ˜¯å›ºå®šçš„,既ä¸èƒ½è¢«é‡æ–°åˆ†é…åQŒä¹Ÿä¸èƒ½è¢«å›žæ”Óž¼Œé™¤éžä½¿ç”¨é€‚当çš?JNI 调用æ¥é‡Šæ”‘Ö®ƒä»¬ã€‚IBM Java æœåŠ¡å›¢é˜Ÿå¯ä»¥å¸®åŠ©¼‹®å®š˜q™ç±»å¼•用åQŒåœ¨˜q™ç§æƒ…况下,分æžå·¥å…·ä¹Ÿå¤§æœ‰ç”¨æ¦ä¹‹åœ°ã€?/P>
¾cÖM¼¼åœŽÍ¼Œå› 䨓¾cÕd—æ˜¯åœ¨å †çš„å¤–éƒ¨å¼•ç”¨çš„ï¼Œå› æ¤ä¹Ÿæ˜¯å›ºå®šçš„。å³ä½¿æ²¡æœ‰å›ºå®šçš„对象åQŒå¤§çš„分é…一般也会导致出现碎片。所òq¸çš„æ˜¯ï¼Œ˜q™ç±»ä¸¥é‡çš„碎片很ž®‘出现ã€?/P>
如果ç”׃ºŽåžƒåœ¾æ”‰™›†é€ æˆ Java 应用½E‹åºä¸æ—¶åœ°åœ™å¿ï¼Œòq¶å‘æ ‡è®°å¯ä»¥å¸®åŠ©å‡å°‘åœé¡¿çš„æ—¶é—ß_¼Œä½¿åº”用程åºè¿è¡Œæ›´òq³ç¨³ã€‚但有时候,òq¶å‘æ ‡è®°å¯èƒ½ä¼šé™ä½Žåº”用程åºçš„åžå能力。å¾è®®åˆ†åˆ«ä‹É用和¼›æ¢òq¶å‘æ ‡è®°åQŒä‹É用相åŒçš„è´Ÿè·æ¥æµ‹é‡å¯¹åº”用½E‹åºæ€§èƒ½çš„媄å“,òq¶åŠ ä»¥æ¯”è¾ƒã€?/P>
但是åQŒè§‚å¯ŸåÆˆå‘æ ‡è®°è¿è¡Œçš„ verbosegc 输出å¯èƒ½æä¾›å¤§é‡å…³äºŽåŠ é€Ÿçš„ä¿¡æ¯ã€‚ä¸éœ€è¦åˆ†æžæ‰“å°å‡ºæ¥çš„记录的æ¯ä¸€éƒ¨åˆ†åQŒæœ‰æ„ä¹‰çš„éƒ¨åˆ†åŒ…æ‹¬åÆˆå‘æ ‡è®°èƒ½å¤ŸæˆåŠŸæ‰«æçš„æ¦‚率åQˆEXHAUSTED å’?ABORTED/HALTEDåQ‰ï¼Œä»¥åŠåŽå°¾U¿ç¨‹èƒ½å¤Ÿåšå¤šž®‘工作ã€?/P>
下é¢çš„三个记录属于åŒä¸€ä¸?Java 应用½E‹åºåQŒæ˜¯åœ¨ä¸€‹Æ¡è¿è¡Œä¸çš„ä¸åŒé˜¶ŒDµåˆ›å»ºçš„åQŒå®ƒä»¬è¯´æ˜Žäº†òq¶å‘˜q行的三¿Uä¸åŒç»“æžœã€?/P>
½W¬ä¸€¿Uå¯èƒ½çš„¾l“æžœæ˜¯åÆˆå‘æ ‡è®°å¾—åˆ?EXHAUSTEDåQ?/P>
˜q™è¡¨æ˜ŽåÆˆå‘æ ‡è®°æŒ‰ç…§æˆ‘ä»¬æ‰€é¢„æœŸçš„é‚£æ ·å·¥ä½œã€‚EXHAUSTED æ„味ç€åŽå°¾U¿ç¨‹èƒ½å¤Ÿåœ¨å‡ºçŽ°åˆ†é…失败之å‰å®Œæˆè‡ªå·Þqš„å·¥ä½œã€‚å› ä¸ºåŽå°çº¿½E‹æ‰«æäº† 3324474 个å—节(而应用程åºçº¿½E‹æ‰«æäº† 53962742 个å—节)åQŒåŽå°çº¿½E‹èƒ½å¤ŸèŽ·å¾—èƒö够的 CPU æ—‰™—´æ¥å‡ž®‘æ€Èš„æ ‡è®°æ—‰™—´ã€‚å› æ¤ï¼ŒSTW ä¸çš„æ ‡è®°é˜¶æ®µåªç”¨äº?51 毫秒åQˆmsåQ‰ï¼Œæ€Èš„ STW æ—‰™—´ä¹Ÿä¸˜q?230 毫秒。这对于 512 MB çš„å †æ¥è¯´åQŒè¿™å·²ç»å¾ˆä¸é”™äº†ã€?/P>
䏋颿˜?ABORTED òq¶å‘æ ‡è®°˜q行åQ?/P>
˜q™æ˜¯æœ€¾pŸç³•的情å†üc€‚åÆˆå‘æ ‡è®°è¢«¾lˆæ¢åQŒä¸»è¦æ˜¯å› 䨓è¦åˆ†é…大型对象和调用äº?System.gc()。如果应用程åºé¢‘¾J地˜q™æ ·åšï¼Œé‚£ä¹ˆž®×ƒ¸èƒ½ä»Žòq¶å‘æ ‡è®°ä¸è޷得好处ã€?/P>
最好是 HALTED òq¶å‘æ ‡è®°åQ?/P>
ä»ŽåÆˆå‘æ ‡è®°çš„应用æ¥çœ‹åQŒHALTED 介于 EXHAUSTED å’?ABORTED 之间åQŒå®ƒè¡¨æ˜Žåªå®Œæˆäº†éƒ¨åˆ†å·¥ä½œã€‚上é¢çš„记录说明åQŒåœ¨˜q›è¡Œä¸‹ä¸€‹Æ¡åˆ†é…失败之å‰ï¼Œæ²¡æœ‰å®Œæˆæ‰«æã€‚在垃圾攉™›†å‘¨æœŸä¸ï¼Œæ ‡è®°é˜¶æ®µèŠÞp´¹äº?274 毫秒åQŒæ€Èš„æ—‰™—´ä¸Šå‡åˆ?414 毫秒ã€?/P>
åœ¨ç†æƒ³çš„æƒ…况下,多数垃圾攉™›†å‘¨æœŸéƒ½åÆˆå‘æ”¶é›†ï¼ˆç”׃ºŽòq¶å‘æ ‡è®°å®Œæˆå…¶å·¥ä½œè€Œè§¦å‘ï¼Œæ ‡è®°ä¸?EXHAUSTEDåQ‰ï¼Œè€Œä¸æ˜¯å‡ºçŽ°åˆ†é…失败。如果应用程åºè°ƒç”?System.gc()åQŒè®°å½•ä¸ä¼šå‡ºçŽ°å¾ˆå¤?ABORTED 行ã€?/P>
在多数应用程åºä¸åQŒåÆˆå‘æ ‡è®°éƒ½å¯ä»¥æ”¹å–„性能åQŒå¯¹äºŽâ€œæ ‡è®°æ ˆæº¢å‡ºâ€ä¹Ÿæœ‰æ‰€å¸®åŠ©ã€‚ä½†æ˜¯ï¼Œå¦‚æžœæ ‡è®°æ ˆæº¢å‡ºæ˜¯ç”׃ºŽ¾~ºé™·é€ æˆçš„,惟一的解军_Šžæ³•å°±æ˜¯ä¿®æ£ç¼ºé™—÷€?/P>
下列命ä×o行开兛_º”é¿å… 使用ã€?/P>
本文½Ž€å•介¾l了 IBM JVM çš„åžƒåœ¾æ”¶é›†å’Œå †ç®¡ç†èƒ½åŠ›ã€‚ä»¥åŽçš„ verbosegc 日志很å¯èƒ½æä¾›æ›´å¤šæœ‰ç”¨çš„ä¿¡æ¯ã€?/P>
æ€È»“ä¸€ä¸‹æ–‡ä¸æå‡ºçš„å»ø™®®åQ?/P>
如æ?zh¨¨n)¨æ‰€è§ï¼Œ˜q™ä¸ªè¯é¢˜å¯ä¸æ˜¯ä¸‰a€ä¸¤è¯ž®Þpƒ½è¯´æ˜Žç™½çš„。但是,åªéœ€è¦æ‰“ä¸€ä¸ªç”µè¯æˆ–者å‘一ž®ç”µåé‚®ä»Óž¼Œž®Þpƒ½ä¸Žæ?zh¨¨n)¨çš„好伙ä¼?IBM Technical Support Team å–å¾—è”ç³»åQ?A >å‚考资æ–?/FONT>ä¸çš„链接是很好的èµïL‚¹åQ‰ã€‚对于æ?zh¨¨n)¨é‡åˆ°çš„特ŒDŠæƒ…å†µï¼Œä»–ä»¬è¦æ¯”ä»ÖM½•æ–‡ç« éƒ½æ›´æ¸…æ¥šã€?/P> Sumit Chawla åœ?IBM eServer 部门ä¸?ISV æä¾› Java 支æŒã€‚æ?zh¨¨n)¨å¯ä»¥é€šè¿‡ sumitc@us.ibm.com 和他è”ç³»ã€?/P> ž®?100 MB çš„åžƒåœ¾æ‰“åŒ…æˆ 50 MB 的包 ¾U§åˆ«: åˆçñ” Jack Shirazi, 董事, JavaPerformanceTuning.com 2004 òq?7 æœ?30 æ—?/P>
éšç€¾|‘å¿—ä½œäØ“å…¬å…±æ—¥è®°çš„æµè¡Œï¼Œ¾|‘å¿—ä¸ÀLœº˜q…速地增长。所以对äº?Blog-City çš„ähæ¥è¯´åQŒéžå¸¸æ¸…楚他们的站点需è¦å‘展和æé«˜ã€‚äØ“äº†æ»¡‘›_…¶å¢žé•¿çš„需è¦ï¼Œè¯¥å…¬å¸æœ€˜q‘刚刚推å‡ÞZº† Blog-City version 2.0。æ£åƒç»å¸¸å‡ºçŽ°çš„æƒ…å†µé‚£æ ·åQŒå½“新的应用½E‹åºè½¬å…¥˜q行阶段æ—Óž¼Œç”׃ºŽå„ç§åŽŸå› åQŒå…¶æ€§èƒ½æ— 法完全满èƒöæœŸæœ›çš„è¦æ±‚,½Hç„¶å‡ºçŽ°éšæœºçš„é•¿æ—‰™—´åº”用½E‹åºè¢«æŒ‚èµïLš„现象˜q˜ä¸æ˜¯æœ€å的情况ã€?/P>
åœ¨å…¶æ ¸å¿ƒåQŒBlog-City ä¾é Blue Dragon Servlet 引擎åQˆCFML 引擎åQ‰å’Œæ•°æ®åº“。ä×o人惊讶的是,所有这些èÊY仉™ƒ½å®¿ä¸»åœ¨è¿è¡?Red Hat Linux 的相当è€çš„ P3 æœºå™¨ä¸Šã€‚è¿™å°æœºå™¨å…·æœ‰å•个硬盘和 512MB 内å˜åQŒè¿™å¯¹äºŽ˜q‡åŽ»çš„è´Ÿè½½æ¥è¯´æ˜¯‘›_¤Ÿå¼ºå¤§çš„,但它æ£åœ¨æ‰¿å—䏿–增长的负载。Blog-City çš„è¿ä½œæ–¹å¼å¾ˆæˆåŠŸåQŒä½†å…¶èµ„æºé™åˆ¶å´æˆäº†å…¶æˆåŠŸèµ\上的¾lŠè„šçŸŸë€‚å°½½Ž¡å¦‚æ¤ï¼Œ˜q™å°±æ˜¯æœªæ¥è¿˜è¦ç‘ô¾lä‹É用一ŒD‰|—¶é—´çš„æ‰€æœ‰ç¡¬ä»¶ã€?/P>
整个˜q‡ç¨‹çš„ç¬¬ä¸€æ¥æ˜¯¼‹®å®š½H然出现应用½E‹åºå‡æ…¢çš„åŽŸå› ã€‚é¦–å…ˆæˆ‘ä»¬æ€€ç–‘çš„å¯¹è±¡æ˜¯åžƒåœ¾æ”¶é›†ã€‚æ£å¦‚我们在 本专æ çš„ä¸Šæœˆæ–‡ç« ä¸æ‰€è®ø™¿°çš„é‚£æ øP¼Œ¼‹®å®šåžƒåœ¾æ”‰™›†å’Œå†…å˜åˆ©ç”¨é—®é¢˜æ˜¯å¦å¯¹åº”用½E‹åºäº§ç”Ÿè´Ÿé¢å½±å“的最å®ÒŽ(gu¨©)˜“çš„æ–¹å¼æ˜¯åQŒè®¾¾|? 从对日志文äšg的最åˆåˆ†æžä¸çœ‹ï¼Œåœ¨è¿™ä¸€åº”用½E‹åºä¸åžƒåœ¾æ”¶é›†çš„瓉™¢ˆæ˜¯æ˜¾è€Œæ˜“è§çš„。秿Uè¿¹è±¡åŒ…æ‹¬åžƒåœ¾æ”¶é›†çš„é¢‘çŽ‡ã€æŒ¾læ—¶é—´å’Œæ€ÖM½“效率都已表明˜q™ä¸€ç‚V€‚高于普通垃圾收集频率的常è§åŽŸå› æ˜¯ï¼Œå †çš„å¤§å°åˆšå¥½‘³ä»¥é€‚åº”æ‰€æœ‰å½“å‰æ£åœ¨ä‹É用的˜q行对象åQŒæ— 法适应新的æ£è¢«åˆ›å¾çš„å¯¹è±¡ã€‚è™½ç„¶åº”ç”¨ç¨‹åºæ¶ˆè€—大é‡å †å¯èƒ½æœ‰è®¸å¤šåŽŸå› ï¼Œä½†ä¸»è¦åŽŸå› å¯èƒ½æ˜¯æ²¡æœ‰‘›_¤Ÿå†…å˜è€Œå¯¼è‡´åžƒåœ¾æ”¶é›†å™¨˜q行åQŒå› 为它设法满èƒö当å‰éœ€è¦ã€‚æ¢å¥è¯è¯ß_¼Œåº”用½E‹åºè¯•å›¾åˆ†é…æ–°å¯¹è±¡ï¼Œä½†å¤±è´¥äº†åQŒå¦‚果失败的è¯ï¼Œž®†è§¦å‘垃圾收集程åºã€‚å¦‚æžœåžƒåœ¾æ”¶é›†å¤±è´¥è€Œæ— æ³•æ¢å¤èƒö够内å˜ï¼Œå®ƒå°†˜q«ä‹Éå¦ä¸€ä¸ªèбè´ÒŽ(gu¨©)›´å¤§çš„垃圾攉™›†½E‹åºå‘生。å³ä½?GC æ¢å¤äº†èƒö够的½Iºé—´æ¥æ»¡‘³çž¬é—´éœ€æ±‚,å¯ä»¥è‚¯å®šçš„æ˜¯åQŒåœ¨åº”用½E‹åº½E‹åºå¦ä¸€‹Æ¡åˆ†é…失败,触å‘å¦ä¸€ä¸?GC 之å‰åQŒæ—¶é—´ä¸ä¼šå¾ˆé•Ñ€‚å› æ¤ï¼Œåº”该å…Ïx³¨é‡å¤æ‰«æ½Iºé—²å †ç©ºé—´çš„æ— 效ä»ÕdŠ¡åQŒè€Œä¸æ˜¯æœåŠ¡äºŽåº”ç”¨½E‹åºçš?JVMã€?/P>
应用½E‹åºé€æ¥æ¶ˆè€—所有å¯ç”¨çš„å †ç©ºé—´å¯èƒ½æœ‰è®¸å¤šåŽŸå› åQŒä½†å¦‚果有更多内å˜çš„è¯ï¼Œä¸´æ—¶è§£å†³æ–ÒŽ(gu¨©)¡ˆž®±æ˜¯é…ç½®æ›´å¤§çš„å †ã€‚å‡è®‘Öº”ç”¨ç¨‹åºæ²¡æœ‰å†…å˜æ³„æ¼ï¼ˆæˆ–者也ž®±æ˜¯æˆ‘ä»¬å¸¸è¯´çš„â€œæ— æ„识åœîC¿ç•™å¯¹è±¡â€ï¼‰åQŒå®ƒ?y¨u)®†æ‰¾åˆîC¸€ä¸ªâ€œè‡ªç„¶â€çñ”åˆ«çš„å †æ¶ˆè€—ï¼Œåœ¨è¿™ä¸ªçñ”别ä¸åQŒGC ž®†èƒ½å¤Ÿå¾ˆé€‚应地得到维æŒï¼ˆé™¤éžå¯¹è±¡åˆ›å¾çš„速度˜q‡å¿«åQŒä»¥è‡?GC æ€ÀL˜¯å¤„于赛跑状æ€ï¼‰ã€‚在˜q™ç§æƒ…å†µä¸‹ï¼Œä»¥åŠæ— æ„识地ä¿ç•™å¯¹è±¡çš„æƒ…况下åQŒæˆ‘们需è¦å¯¹åº”用½E‹åºåšä¸€äº›å˜åŠ¨ï¼Œä»¥ä¾¿èŽ·å¾—æŸäº›æ”¹è¿›ã€?/P> å¦‚æžœä»…ä»…æ˜¯è¿™æ øP¼Œé‚£å°±å¤ªç®€å•了 é—æ†¾çš„æ˜¯åQŒæˆ‘们必™å»é¢å¯¹ä¸¥é…ïLš„çŽ°å®žå› ç´ â€”â€”æ£åœ¨è¿è¡Œçš„æœºå™¨åªæœ‰ 512 MB 内å˜ã€‚æ›´¾pŸçš„æ˜¯ï¼Œæˆ‘们必须与数æ®åº“和其他è¿è¡Œåœ¨æœºå™¨ä¸çš„˜q›ç¨‹å…׃ín该空间。è¦å®Œæ•´ç†è§£˜q™ä¸€ç‚¹äؓ什么至关é‡è¦ï¼Œé¦–å…ˆæ‚(zh¨¨n)¨å¿…™åÀL˜Ž¼‹®ç†è§£åžƒåœ¾æ”¶é›†çš„基本知识åQŒä»¥åŠå®ƒå¦‚何与底层æ“作系¾lŸè¿›è¡Œäº¤äº’ã€?/P>
虚拟内å˜ä¸å†æ˜¯çµä¸¹å¦™è?/STRONG> æ“作¾pÈ»Ÿå·²ç»ä½¿ç”¨è™šæ‹Ÿå†…å˜è®¸å¤šòq´äº†ã€‚æ£å¦‚æ?zh¨¨n)¨æ‰€çŸ¥é“的,虚拟内å˜ä½¿æ“作系¾lŸçš„内å˜çœ‹è“væ¥æ¯”实际的内å˜è¦å¤šï¼Œ˜q™å…许计½Ž—机˜qè¡Œé‚£äº›æ‰€éœ€å†…å˜æ¯”å¯ç”¨ç‰©ç†å†…å˜æ›´å¤§çš„½E‹åºåQŒä¸ä½¿ç”¨å†…å˜çš„应用程åºéƒ¨åˆ†å°†ä¿å˜åœ¨ç£ç›˜ä¸Šã€‚äØ“äº†è¿›ä¸€æ¥ç®€åŒ–,æ“作¾pÈ»ŸåŒæ—¶æŒ‰é¡µ½Ž¡ç†å†…å˜ã€‚é¡µé€šå¸¸åŒ…å« 512 å—节åˆ?8 KBåQŒæ‰€æœ‰é¡µçš„组åˆå°±¾l„æˆäº†ä¸€ä¸ªè™šæ‹Ÿåœ°å€½Iºé—´ã€‚æ“作系¾lŸç»´æŒä¸€ä¸ªé¡µè¡¨ï¼Œç”¨äºŽå‘Šè¯‰æ“作¾pÈ»Ÿå¦‚ä½•æ˜ å°„è™šæ‹Ÿåœ°å€åˆ°ç‰©ç†åœ°å€ã€‚当应用½E‹åºè¦æ±‚æŸä¸ªå†…å˜ä½ç½®çš„内å®ÒŽ(gu¨©)—¶åQŒæ“作系¾lŸï¼ˆæˆ–硬ä»Óž¼‰ž®†è¯†åˆ«åŒ…å«è™šæ‹Ÿåœ°å€çš„页é¢ã€‚ç„¶åŽç¡®å®šè¯¥™åµé¢æ˜¯å¦åœ¨å†…å˜ä¸åQŒå¦‚æžœä¸åœ¨ï¼Œž®†ä¼šæŠ¥å‘Š ™åµé¢é”™è¯¯ã€‚但是有许多¿Uæ–¹å¼æ¥å¤„熙åµé¢é”™è¯¯åQŒæœ€¾lˆçš„¾l“果是,™åµé¢å¿…须从ç£ç›˜è²å…¥åˆ°å†…å˜ä¸ã€‚è¿™æ ·åº”ç”¨ç¨‹åºå°±å¯ä»¥è®‰K—®åˆ°æœ‰æ•ˆè™šæ‹Ÿåœ°å€çš„内å®V€? 如果相关对象æ€ÀL˜¯åœ¨å†…å˜çš„åŒä¸€™åµé¢ä¸Šèšåˆï¼Œé‚£ä¹ˆ GC 的连¾l工作很å¯èƒ½å‡ºçŽ°å›°éš¾ã€‚ä½†æ˜¯çŽ°å®žä¸–ç•Œä¸åQŒç›¸å…›_¯¹è±¡å¾ˆž®‘(如果有的è¯ï¼‰å‡ºçްèšåˆçŽ°è±¡ã€‚å®žé™…ç»“æžœæ˜¯åQŒä¾é 虚拟内å˜çš„¾pÈ»Ÿž®†å¯¼è‡´æ“作系¾lŸå°†™åµä»Žå†…å˜ä¸æ¢å…¥å’Œæ¢å‡ºåQŒå› ä¸ºå®ƒæ ‡è®°ç„¶åŽåºŸå¼ƒå †ç©ºé—ß_¼Œè€Œå½“èšåˆçŽ°è±¡å‘生æ—Óž¼ŒGC ž®†å¾ˆå¤šæ—¶é—´èŠ±åœ¨ç‰å¾…页é¢ä»Ž¼‚盘æ¢å…¥è€Œä¸æ˜¯å®žé™…æ¢å¤å†…å˜ä¸Šã€‚å› æ¤ï¼Œåº”用½E‹åºæ£åœ¨½{‰å¾… GCåQŒè€?GC æ£åœ¨½{‰å¾…¼‚盘åQŒå…¶é—´æœªå®Œæˆä»ÖM½•真æ£çš„工作。由于本¾pÈ»Ÿåªæœ‰ä¸€ä¸ªç£ç›˜ï¼Œòq¶ä¸”å®ƒè¿˜éœ€è¦æ”¯æŒæ•°æ®åº“åQŒå› æ¤æˆ‘们在解决问题时处于两隑֢ƒåœ°ã€‚一斚w¢åQŒæˆ‘们需è¦å¢žåŠ å†…å˜æ•°é‡ï¼Œ˜q™æ ·æˆ‘们å¯ä»¥å‡å°‘ GC 的频率,但å¦ä¸€æ–šw¢åQŒæˆ‘们还需è¦ç¡®ä¿æ•°æ®åº“的完好è¿è¡Œï¼Œè€Œæ•°æ®åº“也是内å˜çš„æ¶ˆè€—大戗÷€‚å› æ¤ï¼Œæˆ‘们需è¦äº†è§£åº”ç”¨ç¨‹åºæ‰€éœ€çš„æœ€ž®å†…å˜æ•°é‡ã€?/P>
æ£å¦‚我们在上月看到的åQŒåœ¨å†—é•¿çš?GC 日志ä¸è¿™ä¸€ä¿¡æ¯å¯ä»¥å¾ˆå®¹æ˜“得刎ͼŒæ— éœ€ä¸ø™¿™ä¸€ä¿¡æ¯è€Œæ‰«ææ•´ä¸ªæ—¥å¿—,我们使用å…è´¹çš?JTune 工具åQˆè¯·å‚阅 å‚考资æ–?/FONT>åQ‰æ¥è§£é‡Šå†—é•¿çš?GC 日志。图 1 昄¡¤ºäº†ç»˜q‡åžƒåœ¾æ”¶é›†ä¹‹åŽçš„内å˜åˆ©ç”¨æƒ…况åQŒå…¶ä¸æˆ‘们将 在图 1 ä¸ï¼Œè“色部分表示部分 GC。橙色区域表½Cºå®Œæ•´çš„ GCåQŒè€Œç²‰è‰²çŸ©å½¢è¡¨½CÞZ¸¤ä¸ªå®Œæ•?GC 在它们之间少于一毫秒之内已ç»å‘ç”Ÿçš„å †åˆ©ç”¨æƒ…å†µã€‚ä»Ž¾l“æžœä¸æˆ‘们看刎ͼŒòq›_‡æ¯?0.257 ¿U’有 12,823 ‹Æ¡æ¸…除。æ€Õd…±æœ?345 ‹Æ¡å®Œæ•´çš„垃圾攉™›†å’?44 ‹Æ¡ç´§æŒ¨ç€çš„垃圾收集。完整垃圾收集的òq›_‡æŒç®‹æ—‰™—´æ˜?7.303 ¿U’,¾l“果表明æœ?9.36% çš„è¿è¡Œæ—¶é—´èŠ±è´¹åœ¨åžƒåœ¾æ”‰™›†½E‹åºä¸Šã€‚虽然这个值å高,它ä»ç„¶ä¿æŒåœ¨ 10% çš„æ£å¸¸æ°´òq³ä¹‹å†…ã€‚å› æ¤ï¼Œåœ¨æœ¬ä¾‹ä¸åQŒGC 是系¾lŸçš„¾Jé‡è´Ÿæ‹…但还没有辑ֈ°ä¸¥é‡çš„地æ¥ã€‚真æ£çš„问题是å˜åœ¨å†…å˜æ³„æ¼ï¼Œ˜q™ä¸€ç‚¹å¯ä»¥ä»Žæ€ÖM½“ä¸Šå †åˆ©ç”¨çŽ‡ä¸æ–增长的‘‹åŠ¿çœ‹å‡ºæ¥ã€?/P>
å³ä‹Éå†…å˜æ³„æ¼æ¶ˆè€—了 50 MB 内å˜åQŒå®ƒä¹Ÿåº”该是¾l过很长一ŒD‰|—¶é—´åŽæ‰å‘生,˜q™ä‹Éå¾—å†…å˜æ³„æ¼åœ¨è¾ƒçŸçš„æµ‹è¯•ä¸å¾ˆå°‘会引人注æ„ã€‚å†…å˜æ³„æ¼çš„实际¾l“果是,它把 JVM çš„å†…å˜æ¶ˆè€—推动到æŸä¸ªç‚¹ï¼Œåœ¨è¯¥ç‚¹å®ƒå¼ø™¿« JVM åQˆä»Žè€Œå¼º˜q«æ“作系¾lŸï¼‰æ¶ˆè€—内å˜ï¼Œå®ƒå¼º˜q«å¯åŠ¨åˆ†™åüc€‚图 2 ž®Þp¯æ˜Žäº†˜q™ä¸€ç‚V€‚æ³¨æ„æ£å¥½åœ¨ 55,000 ¿U’æ ‡è®îC¹‹åŽï¼Œæ¯ä¸€ GC 周期的挾læ—¶é—´ä¸å†…å˜æ¶ˆè€—çªç„¶åœ°æŒç®‹å¢žåŠ ã€?/P> 如æ?zh¨¨n)¨æ‰€æƒ»I¼Œç”׃ºŽåžƒåœ¾æ”‰™›†çš„é˜»å¡žå°†å¯ÆD‡´¾pÈ»Ÿåªæœ‰æ›´å°‘的时间æ¥åˆ†é…¾l™ç”¨æˆïLº¿½E‹ï¼Œå› æ¤ç”¨æˆ·å“åº”å¼€å§‹å¢žåŠ ã€‚åœ¨æ—¥å¿—çš„è¿‡åŽ?10,000 ¿U’ä¸åQŒæˆ‘们看到毋ơ完全收集(æ€Õd…± 15 ‹Æ¡ï¼‰èŠÞp´¹æ—‰™—´‘…过äº?30 ¿U’,òq›_‡æŒç®‹æ—‰™—´å¤§çº¦ 70 ¿U?—â€?˜q™å¯¼è‡´è¶…˜q?10% çš„å¤„ç†æ—¶é—´åˆ†é…给完全 GC。部分收集(˜q™é‡Œåˆšå¥½‘…过äº?1000 ‹Æ¡ï¼‰æ— 法æ£å¸¸å·¥ä½œåQŒåã^凿¯‹Æ¡è¯·æ±‚耗时 1.24 ¿U’,˜qœé«˜äºŽä»¥å‰?11,800 ‹Æ¡æ¸…除ä¸çš„åã^å?0.25 ¿U’ã€?/P>
æœ¬æ–‡ä¸æ¶‰åŠå¤ªæ·Þqš„¾l†èŠ‚åQˆè¯·å‚阅 å‚考资æ–?/FONT>åQŒèŽ·å–分ä»?GC 的详¾l†æ˜qŽÍ¼‰åQŒåˆ†ä»£å †½Iºé—´äº§ç”Ÿäº†â€œå¹´è½ Z€å’Œâ€œå¹´è€â€å¯¹è±¡ï¼Œå®ƒä»¬ä½äºŽåˆ†å¼€çš„å †½Iºé—´ä¸ã€‚在本酾|®ä¸åQŒå¹´è½Õd’Œòq´è€åˆ†ä»£ç©ºé—´å¯ä»¥é€šè¿‡ä¸åŒçš?GC ½Ž—法和ç–略楾l´æŒåQŒä»¥æé«˜ GC 的整体性能ã€? 一¿Uè¿™æ ïLš„½{–略是,˜q›ä¸€æ¥å°†òq´è½»åˆ†ä»£åˆ’分为创建空é—ß_¼Œ¿UîCØ“ EdenåQŒä»¥åŠæ®‹å˜ï¼ˆsurvivoråQ‰ç©ºé—ß_¼Œç”¨äºŽòq¸å˜ä¸€ä¸ªæˆ–者多个收集的òq´è½»å¯¹è±¡ã€‚如果在 Eden 䏿œ‰‘›_¤Ÿçš„å†…å˜æ¥é€‚应新对象创建的è¯ï¼Œ˜q™ä¸€èˆ¬èƒ½å·¥ä½œæ£å¸¸ã€‚å¦‚æžœä¸æ˜¯è¿™¿U情况,那么对象å¯ä»¥åœ¨å¹´è€å¯¹è±¡ç©ºé—´ä¸åˆ›å¾ã€‚åŒæ øP¼Œå¦‚æžœŒD‹å˜½Iºé—´‘›_¤Ÿçš„è¯åQŒé‚£ä¹ˆå¯¹è±¡å°†¿UÕd…¥òq´è€åˆ†ä»£ç©ºé—´ã€‚我们将使用˜q™äº›äº‹å®žæ¥å¸®åŠ©è°ƒä¼˜é‡åˆ°çš„问题ã€?/P> å‡å°‘完全攉™›†çš„æ¬¡æ•?/FONT> Blog-City 所¼„°åˆ°çš„难题是在æŸä¸€éšæœºç‚¹å‡ºçŽ°é•¿çš„æš‚åœæ—¶é—´ã€‚一旦应用程åºå¯åŠ¨å‡ºçŽ°é—®é¢˜ï¼Œä¸é‡æ–°å¯åŠ¨æœºå™¨çš„è¯ï¼Œž®±æ— 法返回跟ítªã€‚由于长旉™—´æš‚åœçš„现象直接与长的 GC 相关åQŒæˆ‘们考虑如果ž®†å¯¹è±¡ä¿æŒåœ¨òq´è½»åˆ†ä»£æ¥å‡ž®‘完å…?GC 的次数。由于完å…?GC 的代价如æ¤ä¹‹å¤§ï¼Œåœ¨å¹´è½Õdˆ†ä»£æ”¶é›†æ›´å¤šå¯¹è±¡èƒ½å¤Ÿå¾—到更çŸçš„æš‚åœæ—‰™—´ã€‚è¦å®Œæˆ˜q™ä¸€ä»ÕdŠ¡åQŒæˆ‘ä»¬è°ƒæ•´äº†ä¸€äº›åžƒåœ¾æ”¶é›†å‚æ•ŽÍ¼ŒåŒ…括 ŒD‹å˜æ¯”率åQˆsurvivor ratioåQ?/I>å’?期é™é˜ˆå€û|¼ˆtenuring thresholdåQ?/I>ã€? ŒD‹å˜æ¯”率用于讄¡½®ä¸Žå¹´è½Õdˆ†ä»£ç©ºé—´æ€ÖM½“大å°ç›¸å…³çš„æ®‹å˜ç©ºé—´çš„大å°ã€‚å¦‚æžœæ®‹å˜æ¯”率设¾|®äØ“ 8åQˆIntel 的默认å€û|¼‰åQŒé‚£ä¹ˆæ¯ä¸€ŒD‹å˜½Iºé—´ž®†æ˜¯ Eden ½Iºé—´çš?1/8 大å°ã€‚å¦ä¸€¿Uè€ƒå¯Ÿå®ƒçš„æ–¹å¼æ˜¯ï¼Œòq´è½»åˆ†ä»£ž®†è¯¥ Eden ½Iºé—´åˆ’分ä¸?10 个相åŒå¤§ž®çš„å€û|¼Œè¯?Eden ž®†åˆ†é…å…¶ä¸çš„ 8 个,æ¯ä¸€ä¸ªæ®‹å˜ç©ºé—´çš„大å°ä¸?1ã€?/P>
我们的å‡è®¾æ˜¯åQŒé€šè¿‡å‡å°‘ŒD‹å˜æ¯”率åQŒæˆ‘们å¯ä»¥å‡ž®‘由于残å˜ç©ºé—´ä¸½Iºé—´çš„缺ä¹ï¼Œå¯¹è±¡˜q‡æ—©åœ°è¢«æå‡ä¸ºå¹´è€åˆ†ä»£çš„å‡ çŽ‡ã€‚å¦ä¸€¿Uæ–¹æ³•æ˜¯å¢žåŠ æœŸé™é˜ˆå€û|¼Œ˜q™æ ·çš„è¯åQŒå¯¹è±¡åœ¨æå‡ä¹‹å‰ž®†éœ€è¦ä¿ç•™æ›´å¤šçš„ GC 事äšg。本瀘q™ä¸ªæƒÏx³•åQŒBlog-City ž®†è®¾¾|®æ›´æ”¹äØ“ é€‰æ‹©ä½Žæš‚åœæ—¶é—´çš„垃圾攉™›†½Ž—法 ç”׃ºŽ˜q™æ¬¡æŠ€æœ¯è°ƒä¼˜çš„ç›®æ ‡ä¹‹ä¸€æ˜¯å‡ž®‘æš‚åœæ—¶é—ß_¼Œæˆ‘们军_®šæŠ›å¼ƒé»˜è®¤çš„啾U¿ç¨‹ã€æ ‡è®°æ¸…扫的垃圾攉™›†½E‹åºã€‚æˆ‘ä»¬é€‰æ‹©é€šè¿‡æ ‡å¿— å›?3 和图 4 的输出展½CÞZº†ä½¿ç”¨æ ‡å¿— ¾l“果图表昄¡¤ºäº†æ˜Žæ˜„¡š„ä¸åŒã€‚虽然ä»ç„¶æœ‰ä¸€ä¸ªå†…å˜æ¼‹zžã€‚å†…å˜æ¶ˆè€—çš„æ€ÀL•°ç›¸æ¯”å‰ä¸€ä¸ªå›¾å·²ç»æ˜¯å¤§å¤§é™ä½Žäº†ã€‚GC æŒç®‹æ—‰™—´çš„快速比较æ½CÞZº†òq´è½»åˆ†ä»£å’Œå¹´è€åˆ†ä»£çš„æ€ÖM½“ GC æŒç®‹æ—‰™—´çš„æ˜Žæ˜‘Ö‡ž®‘ã€?/P> ç”׃ºŽåº”用½E‹åºæ˜¯ä¾é 内å˜çš„åQŒè·Ÿítªå†…å˜æ³„æ¼åƈ消除它们已ç»å˜å¾—‘Šæ¥‘Šé‡è¦ã€‚在本例ä¸ï¼Œç”¨äºŽæ”¯æŒ¾~“嘽{–ç•¥çš„ç»„ä»¶å†³å®šäº†ä¸»è¦æ¼æ´žçš„æ¥æºã€‚从最åŽçš„内å˜åˆ†æžæƒ…况æ¥çœ‹åQˆå›¾ 3åQ‰ï¼Œè™½ç„¶æ¶ˆé™¤äº†ä¸»è¦å†…å˜æ³„æ¼ï¼Œæˆ‘们å¯ä»¥çœ‹åˆ°ä»æœ‰å¦ä¸€ä¸ªâ€œä½Ž¾U§åˆ«çš„â€çš„æ¼æ´žåQŒä½†˜q™ä¸ªæ¼æ´žæ¯”较?y¨u)®ï¼Œå› æ¤å®ƒåœ¨ä¸‹ä¸€ç‰ˆæœ¬å‘布之å‰å¯ä»¥å¿½ç•¥ã€?/P> 本文æå‡ºäº†è®¸å¤šæŒ‘战。首先,我们æ£åœ¨è°ƒä¼˜ä¸€ä¸ªçŽ°å®žä¸çš„应用程åºï¼Œ˜q™æ„å‘³ç€æ›´æ”¹ä¼šå—到很多é™åˆ¶ã€‚第二个挑战是,˜q™é¡¹ä»ÕdŠ¡æ˜¯ä‹Éç”?IRC èŠå¤©å®¤è¿œ½E‹æ“控的。èŠå¤©å®¤ä¸æä¾›ä“Q何çñ”别或质é‡çš„相互通信åQŒè€Œé€šä¿¡åœ¨è¿™¿U类型的ä»ÕdŠ¡ä¸å¾€å¾€æ˜¯å¿…需的。在本例ä¸ï¼Œå›¢é˜Ÿå·²ç»ä¹ 惯了èŠå¤©å®¤çš„真实性,òq¶èƒ½é€šè¿‡˜q™ç§çœŸå®žæ€§æ¯«æ— ä“Q何阻¼„地工作ç€ã€?/P>
最åŽä¹Ÿæ˜¯æœ€å›°éš¾çš„æŒ‘战是我们å—硬件的é™åˆ¶ã€‚由于多¿UåŽŸå› ï¼Œæˆ‘ä»¬ä¸å¯èƒ½äØ“¾pÈ»Ÿæ·ÕdŠ æ–°ç¡¬ä»¶ã€‚å…¶ä¸æœ€å¤§çš„问题是系¾lŸä¸ç‰©ç†å†…å˜çš„æ•°é‡ï¼Œè€?JVM å’?MySQL 需è¦å¤§é‡çš„内å˜ã€‚但是,通过¾pÈ»Ÿåœ°é€ä¸€åº”用许多更改åQŒåƈ度é‡å®ƒä»¬å¯¹ç³»¾lŸäñ”生的影å“åQŒæˆ‘们å¯ä»¥é€æ¥åœ°æ”¹˜q›æ€ÖM½“¾pÈ»Ÿæ€§èƒ½ã€?/P> Jack Shirazi æ˜?JavaPerformanceTuning.com的董事和 Java Performance Tuning, 2nd Edition (O'Reilly) 一书的作者ã€? Kirk Pepperdine is æ˜?Java Performance Tuning.com çš„é¦–å¸æŠ€æœ¯å®˜åQˆChief Technical OfficeråQŒCTOåQ‰ï¼Œ˜q‡åŽ» 15 òq´æ¥ä»–一直专æ”Õd¯¹è±¡æŠ€æœ¯å’Œæ€§èƒ½è°ƒä¼˜ã€‚Kirk æ˜?Ant Developer's Handbook (MacMillan) 一书的åˆè‘—者ã€?/P>
Maximizing Java Performance on AIX: Part 5 - References and Conclusion
Document options
New site feature
Rate this page
Sumit Chawla (sumitc@us.ibm.com), IBM Certified IT Architect and Technical Lead, Java Enablement, IBMThis is the conclusion of the 5-part series providing tips and techniques that are commonly used for tuning Javaâ„?applications for optimum performance on AIX]. We touch upon other interesting areas of Java performance tuning for AIX, look at a few case studies, and then end the series with a list of useful references.
Back to top
-XX
. IBM Java "Sovereign" architecture is not based on Sun HotSpot architecture as well. The easiest, and in most cases the quickest, way is to throw away all Sun-specific settings when running your application on IBM Platforms, and carrying out the fine-tuning as needed. But if you are curious about how some Sun switches map to IBM switches, read on.
Sun Switch
Equivalent IBM Switch
Notes
-Xms, -Xmx
-Xms, -Xmx
These parameters, and their meaning, remain unchanged. You may still need to do heap sizing.
-XX:SurvivorRatio, -XX:NewSize,
-XX:MaxNewSize, -XX:NewRatioNone
These switches can simply be removed, as they are for generational GC which doesn't apply for IBM Java.
-XX:MinHeapFreeRatio, -XX:MaxHeapFreeRatio
-Xminf, -Xmaxf
Heap expansion/shrinkage is controlled by other factors, not just these switches.
-Xverbose:gc, -XX:+PrintGCDetails
-Xverbose:gc
IBM Java verbosegc trace format is quite different from the Sun GC. More detailed tracing can be enabled as needed, but in most cases the default verbosegc traces are sufficient.
-XX:+UseParallelGC, -Xincgc, -XX:+AggressiveHeap
None
These are various types of Garbage Collectors supported by Sun. These do not apply to IBM Java.
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-Xgcpolicy:optavgpause
Concurrent Low-pause collector is close to the IBM Concurrent Mark in intent (but not necessarily in design).
-XX:+CMSParallelRemarkEnabled
None
Not applicable for IBM Java.
-XX:ParallelGCThreads
-Xgcthreads
It is not advisable to change this setting at least for IBM Java.
-Dsun.rmi.dgc.client.gcInterval, -Dsun.rmi.dgc.server.gcInterval
-Dsun.rmi.dgc.client.gcInterval, -Dsun.rmi.dgc.server.gcInterval
See NIO003 in Part 4. schedo
and vmo
has a system-wide effect, so a thorough coverage of these tools is beyond the scope of the current series. See the Resources section for more information on these tools.
Operating system tunings
SPINLOOPTIME
controls the number of times the system will retry a busy lock before yielding to another process. Since the default is 40, a higher value tells the system that it should try a little bit longer for the lock to be freed up. On multiprocessor systems, it results in better performance since a busy lock retry is cheaper than a process context switch.vmo
line sets up the size and number of large pages. If you look at the Java command-line switches, you will see that -Xlp
is being used. This enables Large page support in Java, which is described in more detail here. If you have a memory intensive application, you can experiment with large pages to see if it helps. More information on this topic is available in the SDK Guide accompanying Java. setsched
line is actually a script, not an AIX command. It calls the thread_setsched
kernel service to select fixed-priority round-robin scheduling, with a fixed priority of 40 for the Java process.schedtune
command is also a script from AIX 5.2 onwards, that maps the passed parameters to the new schedo
command. The above line is changing the time slice for fixed-priority threads to 400 ticks. It is also forcing the fixed priority threads to reside in the global run queue.vmtune
command translates the call to an equivalent vmo call, and the above line enables pinning of shared memory segments.
Back to top
topas
, and then with vmstat
, it was seen that Java was the application consuming most CPU. Using tprof, the functions that showed up had GC-related terms in them (e.g. localMark, which is used in Mark phase), so this indicated a possible issue with Java heap sizing. -Xmine
, forcing the heap to grow faster (seeTip MEM003 in Part 3). The result was that a single expansion avoided multiple potential allocation failures.svmon
, it was seen that only around 4 segments, or 1 GB, were being used for native heap, and the fourth segment seemed to be almost empty (see "Balancing Memory" in "Getting more memory in AIX for your Java applications"). -verbose:jni
was added. The extra messages being printed as a result of this switch revealed that the global JNI reference pool was getting exhausted, which is a very rare thing to happen. The global JNI reference pool is large enough to ensure that most normal applications never run even close to exhausting it.
Back to top
Back to top
Java on AIX
AIX
Back to top
Java ç†è®ºä¸Žå®žè·? JVM 1.4.1 ä¸çš„垃圾攉™›†
文档选项
å¯ÒŽ(gu¨©)¤™å늚„评äh(hu¨¢n)
在上月的 Java ç†è®ºä¸Žå®žè·?/I>ä¸ï¼Œä¸“æ 作家 Brian Goetz 回顾了垃圾收集的基本½Ž—æ³•ã€‚æœ¬æœˆï¼Œä»–è¿›ä¸€æ¥æŽ¢è®?JVM 1.4.1 是如何实际处ç†åžƒåœ¾æ”¶é›†çš„åQŒåŒ…括一些针对多处ç†å™¨ç³»¾lŸçš„æ–°åžƒåœ¾æ”¶é›†é€‰é¡¹ã€‚请在本文对应的 讨论论å›ä¸Šä¸Žä½œè€…åŠå…¶ä»–读者分享æ?zh¨¨n)¨å¯Ò?gu¨©)œ¬æ–‡çš„心得åQˆæ?zh¨¨n)¨ä¹Ÿå¯ä»¥å•å‡ÀL–‡ç« 顶部或底部çš?讨论æ¥è®¿é—®è¯¥è®ºå›åQ‰ã€?
回页�/FONT>
OutOfMemoryError
åQ‰ã€?
�1. 代间引用
回页�/FONT>
System.gc()
æ–ÒŽ(gu¨©)³•æ€ÀL˜¯è§¦å‘一个大的收集,˜q™å°±æ˜¯åº”该尽é‡å°‘用(如果ä¸èƒ½å®Œå…¨ä¸ç”¨çš„è¯åQ?System.gc()
çš„åŽŸå› ä¹‹ä¸€åQŒå› ä¸ºå¤§çš„æ”¶é›†è¦æ¯”å°çš„æ”¶é›†èŠ±è´šw•¿å¾—多的时间。没有办法以¾~–程方å¼è§¦å‘ž®çš„æ”‰™›†ã€?
å›?2. 1.4.1 垃圾攉™›†é€‰é¡¹åQˆFolgmann IT-Consulting æä¾›åQ?
-XX:+UseParNewGC
å¯ç”¨åQŒæ˜¯ä¸€ä¸ªå¹´è½ÖM»£å¤åˆ¶æ”‰™›†å™¨ï¼Œå®ƒå°†åžƒåœ¾æ”‰™›†çš„工作分ä¸ÞZ¸Ž CPU æ•°é‡ä¸€æ ·å¤šçš„线½E‹ã€‚åÆˆå‘æ ‡è®?清除攉™›†å™¨ç”± -XX:+UseConcMarkSweepGC
选项å¯ç”¨åQŒå®ƒæ˜¯ä¸€ä¸ªè€ä»£æ ‡è®°-清除攉™›†å™¨ï¼Œå®ƒåœ¨åˆå§‹æ ‡è®°é˜¶æ®µåQˆåŠåœ¨ä»¥åŽæš‚çŸé‡æ–°æ ‡è®°é˜¶ŒDµï¼‰æš‚çŸåœ°åœæ¢æ•´ä¸ªç³»¾lŸï¼Œç„¶åŽæ¢å¤ç”¨æˆ·½E‹åºåQŒåŒæ—¶åžƒåœ¾æ”¶é›†å™¨¾U¿ç¨‹ä¸Žç”¨æˆïL¨‹åºåƈå‘åœ°æ‰§è¡Œã€‚åÆˆè¡Œå¤åˆ¶æ”¶é›†å™¨å’ŒåÆˆå‘æ ‡è®?清除攉™›†å™¨åŸºæœ¬ä¸Šæ˜¯é»˜è®¤çš„å¤åˆ¶æ”‰™›†å™¨å’Œæ ‡è®°-æ•´ç†æ”‰™›†å™¨çš„òq¶å‘版本。由 -XX:+UseParallelGC
å¯ç”¨çš„åÆˆè¡Œæ¸…é™¤æ”¶é›†å™¨æ˜¯å¹´è½ÖM»£æ”‰™›†å™¨ï¼Œé’ˆå¯¹å¤šå¤„ç†å™¨¾pÈ»Ÿä¸Šéžå¸¸å¤§(å‰å—èŠ‚ä»¥åŠæ›´å¤§çš„)å †è¿›è¡Œäº†ä¼˜åŒ–ã€?
回页�/FONT>
-Xmx
åQ‰ã€‚éšç€å †çš„增大åQŒå¤åˆ¶æ”¶é›†ä¼šå˜å¾—æ›´æœ‰æ•ˆï¼Œæ‰€ä»¥åœ¨å¢žå¤§å †æ—¶åQŒæ?zh¨¨n)¨ž®±å‡ž®‘了æ¯ä¸ªå¯¹è±¡çš„æ”¶é›†æˆæœ¬ã€‚é™¤äº†å¢žåŠ æœ€å¤§å †çš„å¤§ž®ï¼Œ˜q˜å¯ä»¥ç”¨é€‰é¡¹ -XX:NewRatio
å¢žåŠ åˆ†é…¾l™å¹´è½ÖM»£çš„空间䆾é¢ã€‚也å¯ä»¥ç”?-Xmn
选项昑ּ指定òq´è½»ä»£çš„大å°ã€‚有兛_¾®è°ƒåžƒåœ¾æ”¶é›†çš„æ›´å¤š¾l†èŠ‚è¯·å‚é˜?å‚考资æ–?/FONT>ä¸çš„å‡ ç¯‡æ–‡ç« ã€?
回页�/FONT>
回页�/FONT>
WeakReference
å’?SoftReference
åQŒåŠ å…¥äº†å¯¹ç¡®å®šå¯¹è±¡æ˜¯å¦å¯ä»¥è¢«åžƒåœ¾æ”‰™›†çš„é¢å¤–考虑ã€?
回页�/FONT>
优化 Java 垃圾攉™›†çš„æ€§èƒ½
文档选项
å¯ÒŽ(gu¨©)¤™å늚„评äh(hu¨¢n)
æ‚(zh¨¨n)¨çš„ Java 应用½E‹åºå……分利用了所˜q行çš?IBM eServer ¼‹¬äšg的能力了å—?在本文ä¸åQŒä½œè€…将介ç»å¦‚何判æ–垃圾攉™›† —â€?Java 虚拟机执行的收回ä¸å†ä½¿ç”¨½Iºé—´çš„åŽåîC“QåŠ?—â€?是å¦è°ƒèŠ‚åˆ°æœ€ä½³çŠ¶æ€ã€‚ç„¶åŽï¼Œä»–å°†æä¾›ä¸€äº›è§£å†›_žƒåœ¾æ”¶é›†é—®é¢˜çš„廸™®®ã€?/BLOCKQUOTE>
回页�/FONT>
å›?1. å †çš„æ¦‚å¿µè§†å›¾
heaptop - heapbase
åQ‰ç”±å‘½ä×oè¡Œå‚æ•?-Xmx
军_®šã€‚è¯¥å‚æ•°å’Œå…¶ä»–å‘½ä»¤è¡Œå‚æ•°éƒ½æ˜¯åœ¨å…³äº?verbosegc å’Œå‘½ä»¤è¡Œå‚æ•°çš?developerWorks æ–‡æ¡£ä¸æ˜q°çš„。heaplimit 指针å¯ä»¥éšç€å †çš„æ‰©å±•上å‡åQŒéšç€å †çš„æ”¶ç¾ƒä¸‹é™ã€‚heaplimit 永远ä¸èƒ½‘…过 heaptopåQŒä¹Ÿä¸èƒ½ä½ŽäºŽä½¿ç”¨ -Xms
指定的åˆå§‹å †å¤§å°ã€‚ä“Qä½•æ—¶å€™å †çš„å¤§ž®éƒ½æ˜?heaplimit - heapbase
�-Xminf
指定的å€û|¼ˆminf 是最ž®è‡ªç”Þq©ºé—ß_¼‰åQŒå †ž®×ƒ¼šæ‰©å±•ã€‚å¦‚æžœæ•´ä¸ªå †çš„è‡ªç”Þq©ºé—´æ¯”例高äº?-Xmaxf
指定的å€û|¼ˆmaxf 是最大自ç”Þq©ºé—ß_¼‰åQŒå †ž®×ƒ¼šæ”¶ç¾ƒã€?CODE>-Xminf å’?-Xmaxf
的默认值分别是 0.3 å’?0.6åQŒå› æ?JVM æ€ÀL˜¯ž®è¯•ž®†å †çš„自ç”Þq©ºé—´æ¯”例维æŒåœ¨ 30% åˆ?60% ä¹‹é—´ã€‚å‚æ•?-Xmine
åQ?I>mine 是最ž®æ‰©å±•大ž®ï¼‰å’?-Xmaxe
åQ?I>maxe 是最大扩展大ž®ï¼‰æŽ§åˆ¶æ‰©å±•的增é‡ã€‚è¿™ 4 ä¸ªå‚æ•°å¯¹å›ºå®šå¤§å°çš„å †ä¸è“v作用åQˆç”¨ç›¸ç‰çš?-Xms
å’?-Xmx
值å¯åŠ?JVMåQŒè¿™æ„å‘³ç€ HeapLimit = HeapTop
åQ‰ï¼Œå› äØ“å›ºå®šå¤§å°çš„å †ä¸èƒ½æ‰©å±•或收¾~©ã€?/P>
-Xgcpolicy:optavgpause
切æ¢ã€‚撰写本文时åQŒæœ€æ–°ç‰ˆæœ¬çš„ JVM 1.4.0 䏿œ‰ä¸€¿U递增压羃模å¼åQŒå®ƒòq¶è¡ŒåŒ–了åQˆparallelizeåQ‰åŽ‹¾~©é˜¶ŒDüc€‚è®¨è®ø™¿™äº›æ¨¡å¼æ—¶åQŒé‡è¦çš„æ˜¯è¦ç†è§£òq¶è¡Œå’Œåƈå‘的区别ã€?/P>
N
ä¸?CPU 的多处ç†å™¨ç³»¾lŸä¸åQŒæ”¯æŒåƈ行模å¼çš„ JVM 在åˆå§‹åŒ–的时候会å¯åЍ N-1
个垃圾收集帮助器¾U¿ç¨‹ã€‚è¿è¡Œåº”用程åºä»£ç 的时候,˜q™äº›¾U¿ç¨‹ä¸€ç›´å¤„于空闲状æ€ï¼Œåªæœ‰å½“å¯åŠ¨åžƒåœ¾æ”¶é›†æ—¶æ‰è°ƒç”¨å®ƒä»¬ã€‚在æŸä¸€ç‰¹å®šçš„阶ŒDµï¼Œä¼šå°†ä¸€äº›å·¥ä½œåˆ†é…给驱动垃圾攉™›†çš„线½E‹å’Œå¸®åŠ©å™¨çº¿½E‹ï¼Œå› æ¤ä¸€å…±æœ‰ N
¾U¿ç¨‹òq¶è¡Œåœ°è¿è¡Œåœ¨ N
-CPU 机器上。如果覼›æ¢òq¶è¡Œæ¨¡å¼åQŒæƒŸä¸€çš„æ–¹æ³•是使用 -Xgcthreads
傿•°æ”¹å˜å¯åŠ¨çš„åžƒåœ¾æ”¶é›†å¸®åŠ©å™¨¾U¿ç¨‹ä¸ªæ•°ã€?/P>
æ ‡è®°
清ç†
压羃
IBM JVM 1.2.2
X
X
X
IBM JVM 1.3.0
P
X
X
IBM JVM 1.3.1
P, C
P
X
IBM JVM 1.4.0
P, C
P
P
回页�/FONT>
-Xms
å’?-Xmx
控制åQŒè¿™äº›å€¼é€šå¸¸æ˜¯æ ¹æ®ç†æƒÏxƒ…况和é‡è´Ÿèähƒ…å†µä¸‹å †çš„ä½¿ç”¨æƒ…å†µçš„ä¼°è®¡æ¥è®„¡½®çš„,ä½?verbosegc å¯ä»¥å¸®åŠ©¼‹®å®š˜q™äº›å€û|¼Œè€Œé¿å…胡ä¹ÞqŒœ‹¹‹ã€‚䏋颿˜¯ä»Žå¯åŠ¨åˆ°å®Œæˆ½E‹åºçš„åˆå§‹åŒ–åQˆæˆ–者进入“就¾lªâ€çжæ€ï¼‰˜q™æ®µæ—‰™—´é‡Œï¼Œä¸€ä¸ªåº”用程åºçš„ verbosegc 输出åQŒå¦‚下所½Cºã€?/P>
<GC[0]: Expanded System Heap by 65536 bytes
<GC[0]: Expanded System Heap by 65536 bytes
<AF[1]: Allocation Failure. need 64 bytes, 0 ms since last AF>
<AF[1]: managing allocation failure, action=1 (0/3983128) (209640/209640)>
<GC(1): GC cycle started Tue Oct 29 11:05:04 2002
<GC(1): freed 1244912 bytes, 34% free (1454552/4192768), in 10 ms>
<GC(1): mark: 9 ms, sweep: 1 ms, compact: 0 ms>
<GC(1): refs: soft 0 (age >= 32), weak 5, final 237, phantom 0>
<AF[1]: completed in 12 ms>
-Xminf
æ ‡è®°åQˆé»˜è®¤äØ“ 30%åQ‰ã€‚æ ¹æ®åº”用程åºçš„使用åQŒä‹Éç”?-Xms
åˆ†é…æ›´å¤§çš„åˆå§‹å †å¯èƒ½ä¼šæ›´å¥½ä¸€äº›ã€‚å‡ ä¹Žå¯ä»¥è‚¯å®šçš„æ˜¯ï¼Œä¸Šä¾‹ä¸çš„应用½E‹åºåœ¨ä¸‹ä¸€‹Æ?AF æ—¶ä¼šå¯ÆD‡´å †æ‰©å±•ã€‚åˆ†é…æ›´å¤§çš„åˆå§‹å †å¯ä»¥é¿å…è¿™¿U情å†üc€‚一旦应用程åºè¿›å…?Ready 状æ€ï¼Œé€šå¸¸ä¸ä¼šå†é‡åˆ?AFåQŒå› æ¤ä¹Ÿž®Þq¡®å®šäº†æ¯”较好的åˆå§‹å †å¤§ž®ã€‚类似地åQŒé€šè¿‡å¢žåŠ åº”ç”¨½E‹åºè´Ÿè²ä¹Ÿå¯ä»¥æŽ¢‹¹‹åˆ°é¿å…出现 OutOfMemory 错误çš?-Xmx
倹{€?/P>
-Xmx60g
åQˆå½“然是 64 ä½çš„ JVMåQ‰ã€‚虽然在很长旉™—´å†…,应用½E‹åºå¯èƒ½ä¸ä¼šé‡åˆ° AFåQŒä½†ä¸€æ—¦å‘ç”?AFåQŒSTW é€ æˆçš„圙å¿å°†å¾ˆéš¾åº”付。下é¢çš„记录å–自 32 GB AIX ¾pÈ»Ÿä¸Šåˆ†é…了 20 GB å †ç©ºé—´çš„ 64 ä½?JVM 1.3.1åQˆbuild caix64131-20021102
åQ‰ï¼Œå®ƒå±•½CÞZº†å¤§åž‹å †åœ¨˜q™æ–¹é¢çš„å½±å“ã€?/P>
<AF[29]: Allocation Failure. need 2321688 bytes, 88925 ms since last AF>
<AF[29]: managing allocation failure, action=1 (3235443800/20968372736)
(3145728/3145728)>
<GC(29): GC cycle started Mon Nov 4 14:46:20 2002
<GC(29): freed 8838057824 bytes, 57% free (12076647352/20971518464),
in 4749 ms>
<GC(29): mark: 4240 ms, sweep: 509 ms, compact: 0 ms>
<GC(29): refs: soft 0 (age >= 32), weak 0, final 1, phantom 0>
<AF[29]: completed in 4763 ms>
-Xms100m -Xmx100m
åQŒé‚£ä¹?JVM ž®†åœ¨æ•´ä¸ªç”Ÿå‘½æœŸä¸æ¶ˆè€?100 MB 的内å˜ï¼Œå³ä‹É利用率丑…过 10%ã€?/P>
-Xinitsh
在开始的时候分é…较大的¾pÈ»Ÿå †ï¼Œä»Žè€Œé¿å…出çŽ?Expanded System Heap 消æ¯ã€‚但˜q™äº›æ¶ˆæ¯å®Œå…¨å¯ä»¥å¿½ç•¥ã€‚ç³»¾lŸå †éšç€éœ€è¦è€Œæ‰©å±•,òq¶ä¸”永远ä¸ä¼šå‘生垃圾攉™›†åQŒå®ƒåªåŒ…å«é‚£äº›åº¦˜q‡äº† JVM 实例整个生命期的对象ã€?/P>
-Xms
å’?-Xmx
ä¸åŒåQ‰ï¼Œåº”用½E‹åºå¯èƒ½é‡åˆ°˜q™æ ·çš„æƒ…å†µï¼Œä¸æ–出现分é…å¤ÞpÓ|è€Œå †æ²¡æœ‰æ‰©å±•ã€‚è¿™ž®±æ˜¯å †å¤±æ•?/I>åQŒæ˜¯ç”׃ºŽå †çš„大å°åˆšåˆšèƒ½å¤Ÿé¿å…扩展但åˆä¸èƒö以解决以åŽçš„分é…å¤ÞpÓ|è€Œé€ æˆçš„。通常åQŒåžƒåœ¾æ”¶é›†å‘¨æœŸé‡Šæ”„¡š„½Iºé—´ä¸ä»…å¯ä»¥æ»¡èƒö当å‰çš„分é…失败,而且˜q˜æœ‰å¾ˆå¤šå¯ä¾›ä»¥åŽçš„分é…请求ä‹É用的½Iºé—´ã€‚ä½†æ˜¯ï¼Œå¦‚æžœå †å¤„äºŽå¤±æ•ˆçŠ¶æ€ï¼Œé‚£ä¹ˆæ¯ä¸ªåžƒåœ¾æ”‰™›†å‘¨æœŸé‡Šæ”¾çš„空间刚刚能够满‘›_½“å‰çš„分é…å¤ÞpÓ|。结果,下一‹Æ¡åˆ†é…请求时åQŒåˆä¼šè¿›å…¥åžƒåœ¾æ”¶é›†å‘¨æœŸï¼Œä¾æ¤¾cÀLŽ¨ã€‚å¤§é‡ç”Ÿå˜æ—¶é—´å¾ˆçŸçš„对象也å¯èƒ½é€ 战q™ç§çŽ°è±¡ã€?/P>
-Xminf
å’?-Xmaxf
的倹{€‚比方说åQŒå¦‚æžœä‹Éç”?-Xminf.5
åQŒå †ž®†å¢žé•¿åˆ°è‡›_°‘æœ?50% 的自ç”Þq©ºé—´ã€‚åŒæ øP¼Œå¢žåŠ -Xmaxf
也是很åˆç†ã€‚如æž?-Xminf.5
½{‰äºŽ 5åQ?CODE>-Xmaxf 为默认å€?0.6åQŒå› ä¸?JVM è¦æŠŠè‡ªç”±½Iºé—´æ¯”ä¾‹ä¿æŒåœ?50% å’?60% 之间åQŒæ‰€ä»¥å°±ä¼šå‡ºçŽ°å¤ªå¤šçš„æ‰©å±•å’Œæ”¶¾~©ã€‚两者相å·?0.3 是一个ä¸é”™çš„选择åQŒè¿™æ ?-Xmaxf.8
å¯ä»¥å¾ˆå¥½åœ°åŒ¹é…?-Xminf.5
�/P>
-Xmine
åQŒæ ¹æ®åº”用程åºçš„è¡ŒäØ“æ¥è®¾¾|®æ‰©å±•大ž®çš„æœ€ž®å€¹{€‚ç›®æ ‡æ˜¯èŽ·å¾—‘›_¤Ÿçš„å¯ç”¨ç©ºé—ß_¼Œä¸ä»…能满‘›_½“å‰çš„è¯äh±‚åQŒè€Œä¸”能满‘³ä»¥åŽçš„很多è¯äh±‚åQŒä»Žè€Œé¿å…过多的垃圾攉™›†å‘¨æœŸã€?CODE>-Xmineã€?CODE>-Xmaxf å’?-Xminf
为控制应用程åºçš„内å˜ä½¿ç”¨ç‰ÒŽ(gu¨©)€§æä¾›äº†å¾ˆå¤§çš„絋zÀL€§ã€?/P>
<AF[50]: Allocation Failure. need 272 bytes, 18097 ms since last AF>
<AF[50]: managing allocation failure, action=1 (0/190698952)
(9584432/10036784)>
<GC(111): mark stack overflow>
<GC(111): freed 77795928 bytes in 1041 ms, 43% free (87380360/200735736)>
<GC(111): mark: 949 ms, sweep: 92 ms, compact: 0 ms>
<GC(111): refs: soft 0 (age >= 32), weak 0, final 0, phantom 0>
<AF[50]: completed in 1042 ms>
<AF[1]: Allocation Failure. need 56 bytes, 0 ms since last AF>
<AF[1]: managing allocation failure, action=1 (0/521140736)
(3145728/3145728)>
<GC(1): GC cycle started Thu Aug 29 19:25:45 2002
<GC(1): freed 321890808 bytes, 61% free (325036536/524286464), in 2776 ms>
<GC(1): mark: 2672 ms, sweep: 104 ms, compact: 0 ms>
<GC(1): refs: soft 0 (age >= 32), weak 11, final 549708, phantom 0>
<AF[1]: completed in 2780 ms>
<AF[212]: Allocation Failure. need 912920 bytes, 34284 ms since last AF>
<AF[212]: managing allocation failure, action=2 (117758504/261028856)>
<GC(273): freed 65646648 bytes in 2100 ms, 70% free (183405152/261028856)>
<GC(273): mark: 425 ms, sweep: 89 ms, compact: 1586 ms>
<GC(273): refs: soft 0 (age >= 32), weak 0, final 0, phantom 0>
<GC(273): moved 755766 objects, 43253888 bytes, reason=0, used x4C0 more
bytes>
<AF[212]: completed in 2101 ms>
ca130-20010615
åQ‰ï¼Œå› æ¤åŽ‹ç¾ƒçš„åŽŸå› ï¼ˆ¾U¢è‰²æ˜„¡¤ºåQ‰æ˜¾½CÞZØ“ 0。但是压¾~?256 MB çš„å †èŠÞp´¹äº?1.5 ¿U’ï¼ä¸ÞZ½•˜q™ä¹ˆå·®ï¼Ÿå†æ¥çœ‹ä¸€çœ‹æœ€åˆçš„è¯äh±‚åQŒæœ€åˆè¯·æ±‚çš„æ˜?912920 å—节 —â€?ž®†è¿‘ 1 MBã€?/P>
<AF[370]: Allocation Failure. need 2241056 bytes, 613 ms since last AF>
<AF[370]: managing allocation failure, action=2 (135487112/1291844600)>
<GC: Wed Oct 16 10:16:46 2002
<GC(455): freed 41815176 bytes in 28663 ms, 13% free (177302288/1291844600)>
<GC(455): mark: 3233 ms, sweep: 328 ms, compact: 25102 ms>
<GC(455): refs: soft 0 (age >= 32), weak 0, final 17, phantom 0>
<GC(455): moved 15822115 objects, 615093008 bytes, reason=1, used x698
more bytes>
<AF[370]: managing allocation failure, action=3 (177302288/1291844600)>
<AF[370]: managing allocation failure, action=4 (177302288/1291844600)>
<AF[370]: clearing all remaining soft refs>
<GC(456): freed 176216 bytes in 3532 ms, 13% free (177478504/1291844600)>
<GC(456): mark: 3215 ms, sweep: 317 ms, compact: 0 ms>
<GC(456): refs: soft 16 (age >= 32), weak 0, final 0, phantom 0>
<GC(457): freed 9592 bytes in 23781 ms, 13% free (177488096/1291844600)>
<GC(457): mark: 3231 ms, sweep: 315 ms, compact: 20235 ms>
<GC(457): refs: soft 0 (age >= 32), weak 0, final 0, phantom 0>
<GC(457): moved 2794668 objects, 110333360 bytes, reason=1, used x30 more
bytes>
<AF[370]: managing allocation failure, action=5 (177488096/1291844600)>
<AF[370]: totally out of heap space>
<AF[370]: completed in 268307 ms>
<GC(455): freed 41815176 bytes in 28663 ms, 13% free
(177302288/1291844600)>
<CON[3]: Concurrent collection, (3457752/533723648) (3145728/3145728),
23273 ms since last CON>
<GC(246): Concurrent EXHAUSTED by Background helper . Target=82856559
Traced=57287216 (3324474+53962742) Free=3457752>
<GC(246): Cards cleaning Done. cleaned:13668 (33 skipped). Initial count
13701 (Factor 0.142)>
<GC(246): GC cycle started Tue Oct 1 00:05:56 2002
<GC(246): freed 436622248 bytes, 82% free (443225728/536869376), in 218 ms>
<GC(246): mark: 51 ms, sweep: 167 ms, compact: 0 ms>
<GC(246): In mark: Final dirty Cards scan: 43 ms 158 cards (total:127 ms)
<GC(246): refs: soft 0 (age >= 32), weak 0, final 5, phantom 0>
<CON[3]: completed in 230 ms>
<AF[164]: Allocation Failure. need 962336 bytes, 75323 ms since last AF>
<AF[164]: managing allocation failure, action=1 (83408328/533723648)
(3145728/3145728)>
<GC(247): Concurrent ABORTED. Target=84703195 Traced=0 (0+0) Free=83408328>
<GC(247): GC cycle started Tue Oct 1 00:06:22 2002
<GC(247): freed 350077400 bytes, 81% free (436631456/536869376), in 896 ms>
<GC(247): mark: 695 ms, sweep: 201 ms, compact: 0 ms>
<GC(247): refs: soft 0 (age >= 32), weak 0, final 7, phantom 0>
<AF[164]: completed in 912 ms>
<CONCURRENT GC Free= 11530600 Expected free space= 11526488 Kickoff=11530370>
< Initial Trace rate is 8.00>
<AF[168]: Allocation Failure. need 139280 bytes, 25520 ms since last AF>
<AF[168]: managing allocation failure, action=1 (11204296/533723648)
(3145728/3145728)>
<GC(251): Concurrent HALTED (state=64). Target=118320773 Traced=35469830
(14765196+20704634) Free=11204296>
<GC(251): No Dirty Cards cleaned (Factor 0.177)>
<GC(251): GC cycle started Tue Oct 1 00:08:06 2002
<GC(251): freed 385174400 bytes, 74% free (399524424/536869376), in 389 ms>
<GC(251): mark: 274 ms, sweep: 115 ms, compact: 0 ms>
<GC(251): In mark: Final dirty Cards scan: 46 ms 2619 cards (total:225 ms)
<GC(251): refs: soft 0 (age >= 32), weak 0, final 6, phantom 0>
<AF[168]: completed in 414 ms>
命ä×o行开å…?/B>
说明
-Xnocompactgc
è¯¥å‚æ•°å®Œå…¨å…³é—压¾~©ã€‚虽然在性能斚w¢æœ‰çŸæœŸçš„好处åQŒæœ€¾lˆåº”用程åºå †ž®†å˜å¾—支¼›È ´¼„Žï¼Œå³ä‹Éå †ä¸æœ‰èƒö够的自由½Iºé—´ä¹Ÿä¼šå¯ÆD‡´ OutOfMemory 错误
-Xcompactgc
ä½¿ç”¨è¯¥å‚æ•°å°†å¯ÆD‡´æ¯ä¸ªåžƒåœ¾æ”‰™›†å‘¨æœŸéƒ½æ‰§è¡ŒåŽ‹¾~©ï¼Œæ— è®ºæ˜¯å¦æœ‰å¿…è¦ã€‚JVM 在压¾~©æ—¶è¦åšå¤§é‡çš„决½{–,在普通模å¼ä¸‹ä¼šæŽ¨˜qŸåŽ‹¾~?/TD>
-Xgcthreads
è¯¥å‚æ•°æŽ§åˆ?JVM 在å¯åŠ¨è¿‡½E‹ä¸åˆ›å¾çš„垃圾收集帮助器¾U¿ç¨‹ä¸ªæ•°ã€‚对äº?N-处ç†å™¨æœºå™¨ï¼Œé»˜è®¤çš„线½E‹æ•°ä¸?N-1。这些线½E‹æä¾›åÆˆè¡Œæ ‡è®°å’Œòq¶è¡Œæ¸…ç†æ¨¡å¼ä¸çš„òq¶è¡Œæœºåˆ¶
回页�/FONT>
-Xms
�CODE>-Xmx �-Xminf
åQŒç›´åˆ?verbosegc 输出¾l™å‡ºåˆ†é…å¤ÞpÓ|æ•°é‡ä¸Žæ¯‹Æ¡åžƒåœ¾æ”¶é›†é€ æˆçš„åœ™å¿æ•°é‡ä¹‹é—´çš„ä¸€ä¸ªå¯æŽ¥å—òqŒ™¡¡ã€‚ä‹É用固定大ž®çš„å †é¿å…æ”¶¾~©æˆ–扩展ã€?
回页�/FONT>
回页�/FONT>
å…Ïx³¨æ€§èƒ½: 调优垃圾攉™›†
文档选项
å¯ÒŽ(gu¨©)¤™å늚„评äh(hu¨¢n)
Kirk Pepperdine, CTO, JavaPerformanceTuning.com如果æ‚(zh¨¨n)¨æ˜¯å½“å‰å†™ç½‘志(bloggingåQ‰ç‹‚çƒè€…ä¸çš„一员,则å¯èƒ½å¬è¯´è¿‡ Blog-CityåQŒè¿™æ˜¯ç”±è‹æ ¼å…°çš„一家å°å…¬å¸ Blog-City Ltd. 拥有和è¿è¥çš„¾|‘å¿—ç«™ç‚¹ã€‚å½“ä¸€äº›æ„æ–™ä¹‹å¤–的性能问题½H然出现æ—Óž¼ŒJava 性能专家 Jack Shirazi å’?Kirk Pepperdine 被邀请帮助进è¡?Blog-City 的技术调整。他们的‹‚€‹¹‹å·¥ä½œå› 为嗼‹¬äšg¾U¦æŸå’Œæ•´ä¸ªé¡¹ç›®æ‰€ä½¿ç”¨çš„通信通é“åQˆIRCã€ftp å’?å¶å°”的电åé‚®ä»Óž¼‰çš„é™åˆ¶è€Œå˜å¾—夿‚ã€?/BLOCKQUOTE>
-verbose:gc
JVM 选项åQŒåƈ‹‚€æŸ¥æ—¥å¿—è¾“å‡ºã€‚å› æ¤æˆ‘们釿–°å¯åŠ¨åº”ç”¨ç¨‹åºï¼Œæ‰“开冗长的垃圾收集日志选项åQŒç„¶åŽè€å¿ƒåœ°ç‰å¾…应用程åºçš„æ€§èƒ½é™ä½Žã€‚我们的è€å¿ƒæ¢æ¥çš„æ˜¯éžå¸¸è¯¦ç»†çš„垃圾收集日志文件ã€?
回页�/FONT>
-Xmx
讄¡½®ä¸?256 MBã€?
å›?1. 垃圾攉™›†ä¹‹åŽçš„内å˜åˆ©ç”¨æƒ…å†?/B>
回页�/FONT>
å›?2. GC æŒç®‹æ—‰™—´
回页�/FONT>
-XX:SurvivorRatio=4
åQŒç„¶åŽé‡æ–°å¯åЍã€?XX:+UseParallelGC
æ¥é‡‡ç”¨åÆˆè¡Œæ‹·è´æ”¶é›†ç¨‹åºã€‚åŒæ øP¼Œæœ‰å…³å®žé™…½Ž—法的细节å¯ä»¥åœ¨ Resources䏿‰¾åˆŽÍ¼Œ˜q™é‡Œéœ€è¦æä¸€ä¸‹çš„æ˜¯ï¼Œ˜q™ä¸€æ ‡å¿—调用了一个多¾U¿ç¨‹æ”‰™›†½E‹åºã€‚线½E‹çš„æ•°é‡è®„¡½®ä¸?CPU 的数é‡ã€‚基于这一事实åQŒäº†è§£äؓ什么啾U¿ç¨‹òq¶è¡Œæ‹¯‚´åžƒåœ¾æ”‰™›†½E‹åºè¦æ¯”ä¼ ç»Ÿçš„æ ‡è®°æ¸…æ‰«ç®—æ³•å·¥ä½œæ›´å¥½æ˜¯å¾ˆå›°éš„¡š„åQŒä½†æ˜¯ä»Žå®žé™…观察ä¸å¯ä»¥ä½“会到æä¾›äº†æŸäº›æ€§èƒ½ä¸Šçš„优势ã€?-XX:SurvivorRatio=4 +XX:+UseParallelGC -server -Xmx256M
˜q行时的¾l“æžœã€?
å›?3. æ–°é…¾|®ä¸‹çš„内å˜ä‹É用情å†?/B>
å›?4. æ–°é…¾|®ä¸‹çš?GC æŒç®‹æ—‰™—´
回页�/FONT>
回页�/FONT>
回页�/FONT>
æ‚(zh¨¨n)¨çŸ¥é“垃圾收集器在干什么å—åQ?/P>
![]() |
¾U§åˆ«: åˆçñ” Jack Shirazi, 董事, JavaPerformanceTuning.com 2004 òq?5 æœ?01 æ—?/P> æ‚(zh¨¨n)¨çš„应用½E‹åºæ˜¯å¦¾l常出现 out-of-memory 错误åQŸç”¨æˆäh˜¯å¦æ„Ÿå—到å“应旉™—´æœ‰äº›ä¸ç¨³å®šï¼Ÿåº”用½E‹åºæ˜¯å¦åœ¨ç›¸å½“长的时间内å˜å¾—没有å“应åQŸåº”用程åºçš„æ€§èƒ½æ˜¯å¦æ˜‘Ö¾—˜qŸç¼“了?如果对ä“Qä½•ä¸€ä¸ªé—®é¢˜çš„å›žç”æ˜¯è‚¯å®šçš„åQŒé‚£ä¹ˆæ?zh¨¨n)¨å¾ˆå¯èƒ½é‡åˆîCº†åžƒåœ¾æ”‰™›†çš„问题了。先别进行优化,且å¬å?JavaPerformanceTuning.com çš?Jack Shirazi å’?Kirk Pepperdine æ¥è§£é‡Šå¦‚何识别垃圾收集问题,òq¶ç”±æ¤å¸®åŠ©æ?zh¨¨n)¨å›žç”˜q™ä¸ªé—®é¢˜åQšæ?zh¨¨n)¨çŸ¥é“垃圾攉™›†å™¨åœ¨òq²ä»€ä¹ˆå—åQ?/BLOCKQUOTE> |