| Jiang's profileN.SpaceBlogLists | Help |
|
June 25 Google的逆袭(Z,原名“用数据说话,看Google 怎样被陷害”)转自新浪blog: http://blog.sina.com.cn/s/blog_60676a3f0100e0xk.html 近日,央视爆出谷歌搜索出现大量黄色词条的信息。一个引起舆论强烈反响的例子是,在谷歌搜索“儿子”竟然也能搜索到黄色词条。那么,事情是怎么发生的呢? 下面我们来看谷歌是如何被陷害的:众所周知,谷歌关键词提醒是计算机自动摘取最近最流行的关键词来生成的。于是某些人利用这一点,大量在谷歌上搜索黄色词汇,陷害了谷歌。 在央视曝光谷歌之前7天:
以下再附上几张类似图表,请注意峰值全部在6月17日,即CCTV节目(6月18日)播出的前一天。 (全年统计)
(本月统计)
为做对比,说明搜索引擎的统计应该是什么样子,我来附上一张对关键词“天气预报”的搜索统计图表,从图中我们可以看到,全年搜索量应该大致呈均匀分布,考虑到搜索引擎的普及使用,会有一个逐渐升高的趋势,但绝不可能出现在某个月份呈直线上升的情况。 那么,还有一种可能,是不是北京的人们在6月份,由于夏天到来,荷尔蒙分泌过多,导致对“儿子母亲不正当关系”这样的黄色词汇搜索过多呢?我们且来看这张对关键词“日本女优”的搜索统计图表,
可以看到,对关键词“日本女优”的搜索量全年大致呈均匀分布,甚至在近期有下降的趋势。那么,这种近期全民荷尔蒙分泌过多的情况也应该被排除了。并不是说对所有黄色信息都有大量的搜索需求。搜索数量呈急剧上升的关键词,只局限在媒体大书特书的几个词汇之中,特别要注意的是其急剧上升阶段和峰值都在媒体报道之前,显然,这不是自然的结果,那么,答案是什么呢?是谁让谷歌如此低俗? March 25 前田约翰《简单法则》第一,减少,就是说,达到简单的最简单方法,就是要有所割舍,割舍一些没用的功能、多余的部分,就能简单许多。 前田约翰简介: February 02 调整 Java 虚拟机 - zthttp://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tprf_tunejvm.html调整 Java 虚拟机应用程序服务器是一个 Java 进程,它需要 Java 虚拟机(JVM)才能运行以及支持它所运行的 Java 应用程序。在配置应用程序服务器的过程中,可以对设置进行微调以改善系统对 JVM 的使用方式。 关于本任务JVM 为基于 Java 的应用程序提供了运行时执行环境。WebSphere Application Server 是 JVM 运行时环境与基于 Java 的服务器运行时的组合。它可以在不同 JVM 提供程序提供的 JVM 上运行。要确定正在运行 Application Server 的 JVM 的提供程序,请从 WebSphere Application Server 的 app_server_root/java/bin 目录中发出 java -fullversion 命令。您也可以检查其中一个服务器的 SystemOut.log。当应用程序服务器启动时,Websphere Application Server 会将关于 JVM 的信息(包括 JVM 提供程序信息)写入此日志文件。 从调整 JVM 的观点看,有两种主要的 JVM 类型:
尽管 JVM 调整操作随 JVM 提供程序的不同而有所变化,但一般的调整概念适用于所有 JVM。这些一般的概念包括:
过程
应该指定的堆大小取决于不同时段的堆使用情况。在堆大小频繁更改的情况下,对 Xms 和 Xmx 参数指定相同的值可以提高性能。 使用 Java -X 选项来查看内存选项列表。
有关其他信息,请参阅下列 DeveloperWorks 文章: 调整 Sun JVM 的垃圾回收器 在 Solaris 平台上,WebSphere Application Server 在 Sun Hotspot JVM 上运行,而不是在 IBM JVM 上运行。对 Sun JVM 使用正确的调整参数以利用其性能优化功能十分重要。 Sun Hotspot JVM 依靠分代垃圾回收来实现最佳性能。下列命令行参数对于调整垃圾回收来说非常有用。
有关调整 Sun JVM 的其他信息,请参阅 Java HotSpot VM 的性能文档。 调整 HP JVM 的垃圾回收器 HP JVM 依靠分代垃圾回收来实现最佳性能。下列命令行参数对于调整垃圾回收来说非常有用。
有关调整 HP 虚拟机的其他信息,请参阅 Java 技术软件 HP-UX 11i。 调整 HP 的 JVM for HP-UX 设置下列选项以提高应用程序性能: -XX:SchedulerPriorityRange=SCHED_NOAGE -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.DevPollSelectorProvider -XX:-ExtraPollBeforeRead 调整 Java 虚拟机 - zthttp://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tprf_tunejvm.html调整 Java 虚拟机应用程序服务器是一个 Java 进程,它需要 Java 虚拟机(JVM)才能运行以及支持它所运行的 Java 应用程序。在配置应用程序服务器的过程中,可以对设置进行微调以改善系统对 JVM 的使用方式。 关于本任务JVM 为基于 Java 的应用程序提供了运行时执行环境。WebSphere Application Server 是 JVM 运行时环境与基于 Java 的服务器运行时的组合。它可以在不同 JVM 提供程序提供的 JVM 上运行。要确定正在运行 Application Server 的 JVM 的提供程序,请从 WebSphere Application Server 的 app_server_root/java/bin 目录中发出 java -fullversion 命令。您也可以检查其中一个服务器的 SystemOut.log。当应用程序服务器启动时,Websphere Application Server 会将关于 JVM 的信息(包括 JVM 提供程序信息)写入此日志文件。 从调整 JVM 的观点看,有两种主要的 JVM 类型:
尽管 JVM 调整操作随 JVM 提供程序的不同而有所变化,但一般的调整概念适用于所有 JVM。这些一般的概念包括:
过程
应该指定的堆大小取决于不同时段的堆使用情况。在堆大小频繁更改的情况下,对 Xms 和 Xmx 参数指定相同的值可以提高性能。 使用 Java -X 选项来查看内存选项列表。
有关其他信息,请参阅下列 DeveloperWorks 文章: 调整 Sun JVM 的垃圾回收器 在 Solaris 平台上,WebSphere Application Server 在 Sun Hotspot JVM 上运行,而不是在 IBM JVM 上运行。对 Sun JVM 使用正确的调整参数以利用其性能优化功能十分重要。 Sun Hotspot JVM 依靠分代垃圾回收来实现最佳性能。下列命令行参数对于调整垃圾回收来说非常有用。
有关调整 Sun JVM 的其他信息,请参阅 Java HotSpot VM 的性能文档。 调整 HP JVM 的垃圾回收器 HP JVM 依靠分代垃圾回收来实现最佳性能。下列命令行参数对于调整垃圾回收来说非常有用。
有关调整 HP 虚拟机的其他信息,请参阅 Java 技术软件 HP-UX 11i。 调整 HP 的 JVM for HP-UX 设置下列选项以提高应用程序性能: -XX:SchedulerPriorityRange=SCHED_NOAGE -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.DevPollSelectorProvider -XX:-ExtraPollBeforeRead Tuning Garbage Collection with the 1.4.2 JavaTM Virtual Machinehttp://java.sun.com/docs/hotspot/gc1.4.2/ Table of Contents 2.1 Performance Considerations 3.2.1 Young Generation Guarantee 4.1When to Use the Throughput Collector 4.2.3 Measurements with the Throughput Collector 4.3 When to Use the Concurrent Low Pause Collector 4.4 The Concurrent Low Pause Collector 4.4.2 Young Generation Guarantee 4.4.7 Measurements with the Concurrent Collector 4.4.8 Parallel Minor Collection Options with the Concurrent Collector 4.5 When to Use the Incremental Low Pause Collector 4.6 The Incremental Low Pause Collector 4.6.1 Measurements with the Incremental Collector 7.2 Frequently Asked Questions 1 IntroductionThe JavaTM 2 Platform, Standard Edition (J2SETM platform) is used for a wide variety of applications from small applets on desktops to web services on large servers. In the J2SE platform version 1.4.1 two new garbage collectors were introduced to make a total of four garbage collectors from which to choose. How should that choice be made and what are the consequences of that choice? This document will describe some of the general features shared by all the garbage collectors. It will then discuss tuning options to take the best advantage of those features in the context of the default single-threaded, stop-the-world collector. Finally, it will discuss the specific features of the three other collectors, and discuss the criteria for choosing one of the four collectors. When does garbage collection performance matter to the user? For many applications it doesn't. That is, the application can perform within its specifications in the presence of garbage collection with pauses of modest frequency and duration. An example where this is not the case (when the default collector is used) would be a large application that scales well to large number of threads, processors, sockets, and a large amount of memory. Amdahl observed that most workloads cannot be perfectly parallelized; some portion is always sequential and does not benefit from parallelism. This is also true for the J2SE platform. In particular, virtual machines for the JavaTM platform up to and including version 1.3.1 do not have parallel garbage collection, so the impact of garbage collection on a multiprocessor system grows relative to an otherwise parallel application. The graph below models an ideal system that is perfectly scalable with the exception of garbage collection. The red line is an application spending only 1% of the time in garbage collection on a uniprocessor system. This translates to more than a 20% loss in throughput on 32 processor systems. At 10% of the time in garbage collection (not considered an outrageous amount of time in garbage collection in uniprocessor applications) more than 75% of throughput is lost when scaling up to 32 processors.
This shows that negligible speed issues when developing on small systems may become principal bottlenecks when scaling up to large systems. However, small improvements in reducing such a bottleneck can produce large gains in performance. For a sufficiently large system it becomes well worthwhile to tune the garbage collector. The default collector should be the first choice for garbage collection and will be adequate for the majority of applications. Each of the other collectors have some added overhead and/or complexity, which is the price for specialized behavior. If the application doesn't need the specialized behavior of the alternate collectors, use the default collector. The exception to this rule is large applications that are heavily threaded and run on hardware with a large amount of memory and a large number of processors. For such applications, first try the aggressive heap option (-XX:+AggressiveHeap) described below. This document was written using the J2SE platform, version 1.4.2, on the SolarisTM Operating Environment (SPARC(R) Platform Edition) as the base platform, because it provides the most scalable hardware and software for the J2SE platform. However, the descriptive text applies to other supported platforms, including Linux, Microsoft Windows, and the Solaris Operating Environment (x86 Platform Edition), to the extent that scalable hardware is available. Although command line options are consistent across platforms, some platforms may have defaults different than those described here. 2 GenerationsOne strength of the J2SE platform is that it shields the complexity of memory allocation and garbage collection from the developer. However, once garbage collection is the principal bottleneck, it is worth understanding some aspects of this hidden implementation. Garbage collectors make assumptions about the way applications use objects, and these are reflected in tunable parameters that can be adjusted for improved performance without sacrificing the power of the abstraction. An object is considered garbage when it can no longer be reached from any pointer in the running program. The most straightforward garbage collection algorithms simply iterate over every reachable object. Any objects left over are then considered garbage. The time this approach takes is proportional to the number of live objects, which is prohibitive for large applications maintaining lots of live data. Beginning with the J2SE platform, version 1.2, the virtual machine incorporated a number of different garbage collection algorithms that are combined using generational collection. While naive garbage collection examines every live object in the heap, generational collection exploits several empirically observed properties of most applications to avoid extra work. The most important of these observed properties is infant mortality. The blue area in the diagram below is a typical distribution for the lifetimes of objects. The X axis is object lifetimes measured in bytes allocated. The byte count on the Y axis is the total bytes in objects with the corresponding lifetime. The sharp peak at the left represents objects that can be reclaimed (i.e., have "died") shortly after being allocated. Iterator objects, for example, are often alive for the duration of a single loop.
Some objects do live longer, and so the distribution stretches out to the the right. For instance, there are typically some objects allocated at initialization that live until the process exits. Between these two extremes are objects that live for the duration of some intermediate computation, seen here as the lump to the right of the infant mortality peak. Some applications have very different looking distributions, but a surprisingly large number possess this general shape. Efficient collection is made possible by focusing on the fact that a majority of objects "die young". To optimize for this scenario, memory is managed in generations, or memory pools holding objects of different ages. Garbage collection occurs in each generation when the generation fills up. Objects are allocated in a generation for younger objects or the young generation, and because of infant mortality most objects die there. When the young generation fills up it causes a minor collection. Minor collections can be optimized assuming a high infant mortality rate. The costs of such collections are, to the first order, proportional to the number of live objects being collected. A young generation full of dead objects is collected very quickly. Some surviving objects are moved to an tenured generation. When the tenured generation needs to be collected there is a major collection that is often much slower because it involves all live objects. The diagram below shows minor collections occurring at intervals long enough to allow many of the objects to die between collections. It is well-tuned in the sense that the young generation is large enough (and thus the period between minor collections long enough) that the minor collection can take advantage of the high infant mortality rate. This situation can be upset by applications with unusual lifetime distributions, or by poorly sized generations that cause collections to occur before objects have had time to die. The default garbage collector is meant to be used by applications large and small. Its default parameters were designed to be effective for most small applications. The default parameters aren't optimal for many server applications. This leads to the central tenet of this document: If the garbage collector has become a bottleneck, you may wish to customize the generation sizes. Check the verbose garbage collector output, and then explore the sensitivity of your individual performance metric to the garbage collector parameters. The default arrangement of generations looks something like this.
At initialization, a maximum address space is virtually reserved but not allocated to physical memory unless it is needed. The complete address space reserved for object memory can be divided into the young and tenured generations. The young generation consists of eden plus two survivor spaces . Objects are initially allocated in eden. One survivor space is empty at any time, and serves as a destination of the next, copying collection of any live objects in eden and the other survivor space. Objects are copied between survivor spaces in this way until they old enough to be tenured, or copied to the tenured generation. Other virtual machines, including the production virtual machine for the J2SE platform, version 1.2 for the Solaris Operating Environment, used two equally sized spaces for copying rather than one large eden plus two small spaces. This means the options for sizing the young generation are not directly comparable; see the Performance FAQ for an example. One portion of the tenured generation called the permanent generation is special because it holds all the reflective data of the virtual machine itself, such as class and method objects. 2.1 Performance ConsiderationsThere are two primary measures of garbage collection performance. Throughput is the percentage of total time not spent in garbage collection, considered over long periods of time. Throughput includes time spent in allocation (but tuning for speed of allocation is generally not needed.) Pauses are the times when an application appears unresponsive because garbage collection is occurring. Users have different requirements of garbage collection. For example, some consider the right metric for a web server to be throughput, since pauses during garbage collection may be tolerable, or simply obscured by network latencies. However, in an interactive graphics program even short pauses may negatively affect the user experience. Some users are sensitive to other considerations. Footprint is the working set of a process, measured in pages and cache lines. On systems with limited physical memory or many processes, footprint may dictate scalability. Promptness is the time between when an object becomes dead and when the memory becomes available, an important consideration for distributed systems, including remote method invocation (RMI). In general, a particular generation sizing chooses a trade-off between these considerations. For example, a very large young generation may maximize throughput, but does so at the expense of footprint, promptness, and pause times. young generation pauses can be minimized by using a small young generation at the expense of throughput. To a first approximation, the sizing of one generation does not affect the collection frequency and pause times for another generation. There is no one right way to size generations. The best choice is determined by the way the application uses memory as well as user requirements. For this reason the virtual machine's default garbage collectior may not be optimal, and may be overridden by the user in the form of command line options, described below. 2.2 MeasurementThroughput and footprint are best measured using metrics particular to the application. For example, throughput of a web server may be tested using a client load generator, while footprint of the server might be measured on the Solaris Operating Environment using the pmap command. On the other hand, pauses due to garbage collection are easily estimated by inspecting the diagnostic output of the virtual machine itself. The command line argument -verbose:gc prints information at every collection. Note that the format of the -verbose:gc output is subject to change between releases of the J2SE platform. For example, here is output from a large server application: [GC 325407K->83000K(776768K), 0.2300771 secs] Here we see two minor collections and one major one. The numbers before and after the arrow 325407K->83000K (in the first line) indicate the combined size of live objects before and after garbage collection, respectively. After minor collections the count includes objects that aren't necessarily alive but can't be reclaimed, either because they are directly alive, or because they are within or referenced from the tenured generation. The number in parenthesis (776768K)(in the first line) is the total available space, not counting the space in the permanent generation, which is the total heap minus one of the survivor spaces. The minor collection took about a quarter of a second. 0.2300771 secs (in the first line) The format for the major collection in the third line is similar. The flag -XX:+PrintGCDetails prints additional information about the collections. The additional information printed with this flag is liable to change with each version of the virtual machine. The additional output with the -XX:+PrintGCDetails flag in particular changes with the needs of the development of the Java Virtual Machine. An example of the output with -XX:+PrintGCDetails for the J2SE platform, version 1.4.2 is shown here. [GC [DefNew: 64575K->959K(64576K), 0.0457646 secs] 196016K->133633K(261184K), 0.0459067 secs]] indicates that the minor collection recovered about 98% of the young generation, DefNew: 64575K->959K(64576K) and took about 46 milliseconds. 0.0457646 secs The usage of the entire heap was reduced to about 51% 196016K->133633K(261184K) and that there was some slight additional overhead for the collection (over and above the collection of the young generation) as indicated by the final time: 0.0459067 secs The flag -XX:+PrintGCTimeStamps will additionally print a time stamp at the start of each collection. 111.042: [GC 111.042: [DefNew: 8128K->8128K(8128K), 0.0000505 secs]111.042: [Tenured: 18154K->2311K(24576K), 0.1290354 secs] 26282K->2311K(32704K), 0.1293306 secs] The collection starts about 111 seconds into the execution of the application. The minor collection starts at about the same time. Additionally the information is shown for a major collection delineated by Tenured. The tenured generation usage was reduced to about 10% 18154K->2311K(24576K) and took about .13 seconds. 0.1290354 secs 3 Sizing the GenerationsA number of parameters affect generation size. The following diagram illustrates the difference between committed space and virtual space in the heap. At initialization of the virtual machine, the entire space for the heap is reserved. The size of the space reserved can be specified with the -Xmx option. If the value of the -Xms parameter is smaller than the value of the -Xmx parameter, not all of the space that is reserved is immediately committed to the virtual machine. The uncommitted space is labeled "virtual" in this figure. The different parts of the heap (permanent generation, tenured generation, and young generation) can grow to the limit of the virtual space as needed. Some of the parameters are ratios of one part of the heap to another. For example the parameter NewRatio denotes the relative size of the tenured generation to the young generation. These parameters are discussed below.
3.1 Total HeapSince collections occur when generations fill up, throughput is inversely proportional to the amount of memory available. Total available memory is the most important factor affecting garbage collection performance. By default, the virtual machine grows or shrinks the heap at each collection to try to keep the proportion of free space to live objects at each collection within a specific range. This target range is set as a percentage by the parameters -XX:MinHeapFreeRatio=<minimum> and -XX:MaxHeapFreeRatio=<maximum>, and the total size is bounded below by -Xms and above by -Xmx . The default parameters for the Solaris Operating Environment (SPARC Platform Edition) are shown in this table: -XX:MinHeapFreeRatio= 40 -XX:MaxHeapFreeRatio= 70 -Xms 3670k -Xmx 64m With these parameters if the percent of free space in a generation falls below 40%, the size of the generation will be expanded so as to have 40% of the space free, assuming the size of the generation has not already reached its limit. Similarly, if the percent of free space exceeds 70%, the size of the generation will be shrunk so as to have only 70% of the space free as long as shrinking the generation does not decrease it below the minimum size of the generation. Large server applications often experience two problems with these defaults. One is slow startup, because the initial heap is small and must be resized over many major collections. A more pressing problem is that the default maximum heap size is unreasonably small for most server applications. The rules of thumb for server applications are: Unless you have problems with pauses, try granting as much memory as possible to the virtual machine. The default size (64MB) is often too small. Setting -Xms and -Xmx to the same value increases predictability by removing the most important sizing decision from the virtual machine. On the other hand, the virtual machine can't compensate if you make a poor choice. Be sure to increase the memory as you increase the number of processors, since allocation can be parallelized. A description of other virtual machine options can be found at http://java.sun.com/docs/hotspot/VMOptions.html 3.2 The Young GenerationThe second most influential knob is the proportion of the heap dedicated to the young generation. The bigger the young generation, the less often minor collections occur. However, for a bounded heap size a larger young generation implies a smaller tenured generation, which will increase the frequency of major collections. The optimal choice depends on the lifetime distribution of the objects allocated by the application. By default, the young generation size is controlled by NewRatio. For example, setting -XX:NewRatio=3 means that the ratio between the young and tenured generation is 1:3. In other words, the combined size of the eden and survivor spaces will be one fourth of the total heap size. The parameters NewSize and MaxNewSize bound the young generation size from below and above. Setting these equal to one another fixes the young generation, just as setting -Xms and -Xmx equal fixes the total heap size. This is useful for tuning the young generation at a finer granularity than the integral multiples allowed by NewRatio. 3.2.1 Young Generation GuaranteeIn an ideal minor collection the live objects are copied from one part of the young generation (the eden space plus the first survivor space) to another part of the young generation (the second survivor space). However, there is no guarantee that all the live objects will fit into the second survivor space. To ensure that the minor collection can complete even if all the objects are live, enough free memory must be reserved in the tenured generation to accommodate all the live objects. In the worst case, this reserved memory is equal to the size of eden plus the objects in non-empty survivor space. When there isn't enough memory available in the tenured generation for this worst case, a major collection will occur instead. This policy is fine for small applications, because the memory reserved in the tenured generation is typically only virtually committed but not actually used. But for applications needing the largest possible heap, an eden bigger than half the virtually committed size of the heap is useless: only major collections would occur. Note that the young generation guarantee applies to all of the collectors with the exception of the throughput collector . The throughput collector will proceed with a young generation collection, and if the tenured generation cannot accommodate all the promotions from the young generation, both generations are collected. If desired, the parameter SurvivorRatio can be used to tune the size of the survivor spaces, but this is often not as important for performance. For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6. In other words, each survivor space will be one eighth of the young generation (not one seventh, because there are two survivor spaces). If survivor spaces are too small, copying collection overflows directly into the tenured generation. If survivor spaces are too large, they will be uselessly empty. At each garbage collection the virtual machine chooses a threshold number of times an object can be copied before it is tenured. This threshold is chosen to keep the survivors half full. An option, -XX:+PrintTenuringDistribution, can be used to show this threshold and the ages of objects in the new generation. It is also useful for observing the lifetime distribution of an application. Here are the default values for the Solaris Operating Environment (SPARC Platform Edition): NewRatio 2 (client JVM: 8) NewSize 2228k MaxNewSize unlimited SurvivorRatio 32 The maximum size of the young generation will be calculated from the maximum size of the total heap and NewRatio. The "unlimited" default value for MaxNewSize means that the calculated value is not limited by MaxNewSize unless a value for MaxNewSize is specified on the command line. The rules of thumb for server applications are: First decide the total amount of memory you can afford to give the virtual machine. Then graph your own performance metric against young generation sizes to find the best setting. Unless you find problems with excessive major collection or pause times, grant plenty of memory to the young generation. Increasing the young generation becomes counterproductive at half the total heap or less (whenever the young generation guarantee cannot be met). Be sure to increase the young generation as you increase the number of processors, since allocation can be parallelized. 4 Types of CollectorsThe discussion to this point has been about the default collector. In the J2SE platform, version 1.4.2 there are three additional collectors. Each is a generational collector which has been implemented to emphasize the throughput of the application or low garbage collection pause times.
Note that -XX:+UseParallelGC should not be used with -XX:+UseConcMarkSweepGC. The argument parsing in the J2SE platform, version 1.4.2 should only allow legal combinations of command line options for garbage collectors, but earlier releases may not detect all illegal combinations and the results for illegal combinations are unpredictable. Always try the default collector on your application before trying one of the other collectors. Tune the heap size for your application and then consider what requirements of your application are not being met. Based on the latter, consider using one of the other collectors. 4.1When to Use the Throughput CollectorUse the throughput collector when you want to improve the performance of your application with larger numbers of processors. In the default collector garbage collection is done by one thread, and therefore garbage collection adds to the serial execution time of the application. The throughput collector uses multiple threads to execute a minor collection and so reduces the serial execution time of the application. A typical situation is one in which the application has a large number of threads allocating objects. In such an application it is often the case that a large young generation is needed. 4.2 The Throughput CollectorThe throughput collector is a generational collector similar to the default collector but with multiple threads used to do the minor collection. The major collections are essentially the same as with the default collector. By default on a host with N CPUs, the throughput collector uses N garbage collector threads in the collection. The number of garbage collector threads can be controlled with a command line option (see below). On a host with 1 CPU the throughput collector will likely not perform as well as the default collector because of the additional overhead for the parallel execution (e.g., synchronization costs). On a host with 2 CPUs the throughput collector generally performs as well as the default garbage collector and a reduction in the minor garbage collector pause times can be expected on hosts with more than 2 CPUs. The throughput collector can be enabled by using command line flag -XX:+UseParallelGC. The number of garbage collector threads can be controlled with the ParallelGCThreads command line option (-XX:ParallelGCThreads=<desired number>). The size of the heap needed with the throughput collector to first order is the same as with the default collector. Turning on the throughput collector should just make the minor collection pauses shorter. Because there are multiple garbage collector threads participating in the minor collection there is a small possibility of fragmentation due to promotions from the young generation to the tenured generation during the collection. Each garbage collection thread reserves a part of the tenured generation for promotions and the division of the available space into these "promotion buffers" can cause a fragmentation effect. Reducing the number of garbage collector threads will reduce this fragmentation effect as will increasing the size of the tenured generation. 4.2.1 Adaptive SizingA feature available with the throughput collector in the J2SE platform, version 1.4.1 and later releases is the use of adaptive sizing (-XX:+UseAdaptiveSizePolicy), which is on by default. Adaptive sizing keeps statistics about garbage collection times, allocation rates, and the free space in the heap after a collection. These statistics are used to make decisions regarding changes to the sizes of the young generation and tenured generation so as to best fit the behavior of the application. Use the command line option -verbose:gc to see the resulting sizes of the heap. 4.2.2 AggressiveHeapThe -XX:+AggressiveHeap option inspects the machine resources (size of memory and number of processors) and attempts to set various parameters to be optimal for long-running, memory allocation-intensive jobs. It was originally intended for machines with large amounts of memory and a large number of CPUs, but in the J2SE platform, version 1.4.1 and later it has shown itself to be useful even on four processor machines. With this option the throughput collector (-XX:+UseParallelGC) is used along with adaptive sizing (-XX:+UseAdaptiveSizePolicy). The physical memory on the machines must be at least 256MB before AggressiveHeap can be used. The size of the initial heap is calculated based on the size of the physical memory and attempts to make maximal use of the physical memory for the heap (i.e., the algorithms attempt to use heaps nearly as large as the total physical memory). 4.2.3 Measurements with the Throughput CollectorThe verbose garbage collector output is the same for the throughput collector as with the default collector. 4.3 When to Use the Concurrent Low Pause CollectorUse the concurrent low pause collector if your application would benefit from shorter garbage collector pauses and can afford to share processor resources with the garbage collector when the application is running. Typically applications which have a relatively large set of long-lived data (a large tenured generation), and run on machines with two or more processors tend to benefit from the use of this collector. However, this collector should be considered for any application with a low pause time requirement. Optimal results have been observed for interactive applications with tenured generations of a modest size on a single processor. 4.4 The Concurrent Low Pause CollectorThe concurrent low pause collector is a generational collector similar to the default collector. The tenured generation is collected concurrently with this collector. This collector attempts to reduce the pause times needed to collect the tenured generation. It uses a separate garbage collector thread to do parts of the major collection concurrently with the applications threads. The concurrent collector is enabled with the command line option -XX:+UseConcMarkSweepGC. For each major collection the concurrent collector will pause all the application threads for a brief period at the beginning of the collection and toward the middle of the collection. The second pause tends to be the longer of the two pauses and multiple threads are used to do the collection work during that pause. The remainder of the collection is done with a garbage collector thread that runs concurrently with the application. The minor collections are done in a manner similar to the default collector although multiple garbage collector threads are used to reduce the minor collection times. See "Parallel Minor Collection Options with the Concurrent Collector" below for information on using multiple threads with the concurrent low pause collector. The techniques used in the concurrent collector (for the collection of the tenured generation) are described at: http://research.sun.com/techrep/2000/abstract-88.html 4.4.1 Overhead of ConcurrencyThe concurrent collector trades processor resources (which would otherwise be available to the application) for shorter major collection pause times. The concurrent part of the collection is done by a single garbage collection thread. On an N processor system when the concurrent part of the collection is running, it will be using 1/Nth of the available processor power. On a uniprocessor machine it would be fortuitous if it provided any advantage. It conceivably could break up a single long pause into several shorter pauses (a pause being defined in this case as the absence of any application threads running) but that is not the intent of the concurrent collector. The concurrent collector also has some additional overhead costs that will take away from the throughput of the applications, and some inherent disadvantages (e.g., fragmentation) for some types of applications. On a two processor machine there is a processor available for applications threads while the concurrent part of the collection is running, so running the concurrent garbage collector thread does not "pause" the application. There may be reduced pause times as intended for the concurrent collector but again less processor resources are available to the application and some slowdown of the application should be expected. As N increases, the reduction in processor resources due to the running of the concurrent garbage collector thread becomes less, and the advantages of the concurrent collector become more. 4.4.2 Young Generation GuaranteeAs with the default collector a minor collection may require enough space in the tenured generation to accommodate all the objects in eden and one survivor space. Because fragmentation can occur in a concurrent collection, the requirement for this guarantee is more severe with the concurrent collector. There has to be enough contiguous space available in the tenured generation for all the objects in eden and one survivor space because there is no a priori way (except at a significant performance cost) to know the distribution of the sizes in eden and the one survivor space. A larger heap is almost always needed when the concurrent collector is used as compared to the default collector. As with the default collector the space in the tenured generation must be reserved but does not actually have to be used. As a rough estimate choose the appropriate young generation and tenured generation heap sizes as would be appropriate for the default collector, and then increase the tenured generation size by the equivalent of the young generation size for the concurrent collector. This is a very rough approximation and the correct values are application dependent. 4.4.3 Full CollectionsThe concurrent collector uses a single garbage collector thread that runs simultaneously with the application threads with the goal of completing the collection of the tenured generation before it becomes full. In normal operation, the concurrent collector is able to do most of its work with the application threads still running, so only brief pauses are seen by the application threads. As a fall back, if the concurrent collector is unable to finish before the tenured generation fills up, the application is paused and the collection is completed with all the application threads stopped. Such collections with the application stopped are referred to as full collections and are a sign that some adjustments need to be made to the concurrent collection parameters. 4.4.4 Floating GarbageA garbage collector works to find the live objects in the heap. Because application threads and the garbage collector thread run concurrently, objects that are found to be alive by the garbage collector thread may become dead by the time collection finishes. Such objects are referred to as floating garbage. The amount of floating garbage depends on the length of the concurrent collection (more time for the applications threads to discard an object) and on the particulars of the application. As a rough rule of thumb try increasing the size of the tenured generation by 20% to account for the floating garbage. Floating garbage is collected at the next garbage collection. 4.4.5 PausesThe concurrent collector pauses an application twice during a concurrent collection cycle. The first pause is to mark as live the objects directly reachable from the roots (e.g., objects on thread stack, static objects and so on) and elsewhere in the heap (e.g., the young generation). This first pause is referred to as the initial mark. The second pause comes at the end of the marking phase and finds objects that were missed during the concurrent marking phase due to the concurrent execution of the application threads. The second pause is referred to as the remark. 4.4.6 Concurrent PhasesThe concurrent marking occurs between the initial mark and the remark. During the concurrent marking the concurrent garbage collector thread is executing and using processor resources that would otherwise be available to the application. After the remark there is a concurrent sweeping phase which collects the dead objects. During this phase the concurrent garbage collector thread is again taking processor resources from the application. After the sweeping phase the concurrent collector sleeps until the start of the next major collection. 4.4.7 Measurements with the Concurrent CollectorBelow is output for -verbose:gc with -XX:+PrintGCDetails (some details have been removed). Note that the output for the concurrent collector is interspersed with the output from the minor collections. Typically many minor collections will occur during a concurrent collection cycle. The CMS-initial-mark: indicates the start of the concurrent collection cycle. The CMS-concurrent-mark: indicates the end of the concurrent marking phase as CMS-concurrent-sweep: marks the end of the concurrent sweeping phase. Not discussed before is the precleaning phase indicated by CMS-concurrent-preclean: which represents work that can be done concurrently and is in preparation for the remark phase CMS-remark. The final phase is indicated by the CMS-concurrent-reset: and is in preparation for the next concurrent collection. [GC [1 CMS-initial-mark: 13991K(20288K)] 14103K(22400K), 0.0023781 secs] [GC [DefNew: 2112K->64K(2112K), 0.0837052 secs] 16103K->15476K(22400K), 0.0838519 secs] ... [GC [DefNew: 2077K->63K(2112K), 0.0126205 secs] 17552K->15855K(22400K), 0.0127482 secs] [CMS-concurrent-mark: 0.267/0.374 secs] [GC [DefNew: 2111K->64K(2112K), 0.0190851 secs] 17903K->16154K(22400K), 0.0191903 secs] [CMS-concurrent-preclean: 0.044/0.064 secs] [GC[1 CMS-remark: 16090K(20288K)] 17242K(22400K), 0.0210460 secs] [GC [DefNew: 2112K->63K(2112K), 0.0716116 secs] 18177K->17382K(22400K), 0.0718204 secs] [GC [DefNew: 2111K->63K(2112K), 0.0830392 secs] 19363K->18757K(22400K), 0.0832943 secs] ... [GC [DefNew: 2111K->0K(2112K), 0.0035190 secs] 17527K->15479K(22400K), 0.0036052 secs] [CMS-concurrent-sweep: 0.291/0.662 secs] [GC [DefNew: 2048K->0K(2112K), 0.0013347 secs] 17527K->15479K(27912K), 0.0014231 secs] [CMS-concurrent-reset: 0.016/0.016 secs] [GC [DefNew: 2048K->1K(2112K), 0.0013936 secs] 17527K->15479K(27912K), 0.0014814 secs] The initial mark pause is typically short relative to the minor collection pause time. The times of the concurrent phases (concurrent mark, concurrent precleaning, and concurrent sweep) may be relatively long (as in the example above) when compared to a minor collection pause but the application is not paused during the concurrent phases. The remark pause is affected by the specifics of the application (e.g., a higher rate of modifying objects can increase this pause) and the time since the last minor collection (i.e., more objects in the young generation may increase this pause). 4.4.8 Parallel Minor Collection Options with the Concurrent CollectorOn a multiple processor platform, the default for the UseParNewGC option is true. If the UseParNewGC option is in use the remark pauses may be decreased with the CMSParallelRemarkEnabled option. -XX:+CMSParallelRemarkEnabled 4.5 When to Use the Incremental Low Pause CollectorUse the incremental low pause collector when your application can afford to trade longer and more frequent young generation garbage collection pauses for shorter tenured generation pauses. A typical situation is one in which a larger tenured generation is required (lots of long-lived objects), a smaller young generation will suffice (most objects are short-lived and don't survive the young generation collection), and only a single processor is available. 4.6 The Incremental Low Pause CollectorThe incremental low pause collector is a generational collector similar to the default collector. The minor collections are done with the same young generation collector as the default collector. Do not use either -XX:+UseParallelGC or -XX:+UseParNewGC with this collector. The major collections are done incrementally on the tenured generation. This collector (also known as the train collector) collects portions of the tenured generation at each minor collection. The goal of the incremental collector is to avoid very long major collection pauses by doing portions of the major collection work at each minor collection. The incremental collector will sometimes find that a non-incremental major collection (as is done in the default collector) is required in order to avoid running out of memory. This collector can cause some fragmentation of the heap, so sometimes a larger tenured generation heap size will be required, as compared to the default mark-sweep-compact collector. In order to collect a portion of the tenured generation at each minor collection additional information is maintained by the incremental collector. The overhead of maintaining this information increases the overall cost of garbage collection and throughput is typically less than when using the default mark sweep collector. The incremental collector should be used by first trying the default collector and sizing the heap as discussed for the default collector. If the major pauses cannot be reduced to an acceptable level by adjusting the sizes of the generations in the heap, try the incremental collector with the same generation sizes first. Then vary the generation sizes to fit your application.
4.6.1 Measurements with the Incremental CollectorFor details on the incremental collector in addition to the -verbose:gc command line flag, add the flag -XX:+PrintGCDetails (which first became available in the J2SE platform, version 1.4.1). A typical line of output with the details flag will look like this. [GC [DefNew: 2074K->25K(2112K), 0.0050065 secs][Train: 1676K->1633K(63424K), 0.0082112 secs] 3750K->1659K(65536K), 0.0138017 secs] This line says that a young generation collection was done and took about 5 milliseconds. An incremental collection was done (indicated by the Train: part of the line) and took about 8 milliseconds. If a full collection is done instead of an incremental collection, the line will include Train MSC: which indicates a full (mark-sweep-compact) collection was done. [GC [DefNew: 2049K->2049K(2112K), 0.0003304 secs][Train MSC: 61809K->357K(63424K), 0.3956982 secs] 63859K->394K(65536K), 0.3987650 secs] Also in this line you can see that the minor collection was not effective. Before the collection 2049KB of space in the young generation was occupied and after the collection the same amount was occupied. This indicates that the contiguous free space in the tenured generation was not enough to satisfy the young generation guarantee. 5 Other ConsiderationsFor most applications the permanent generation is not relevant to garbage collector performance. However, some applications dynamically generate and load many classes. For instance, some implementations of JSPTM pages do this. If necessary, the maximum permanent generation size can be increased with MaxPermSize. Some applications interact with garbage collection by using finalization and weak/soft/phantom references. These features can create performance artifacts at the Java programming language level. An example of this is relying on finalization to close file descriptors, which makes an external resource (descriptors) dependent on garbage collection promptness. Relying on garbage collection to manage resources other than memory is almost always a bad idea. Another way applications can interact with garbage collection is by invoking full garbage collections explicitly, such as through the System.gc() call. These calls force major collection, and inhibit scalability on large systems. The performance impact of explicit garbage collections can be measured by disabling explicit garbage collections using the flag -XX:+DisableExplicitGC. One of the most commonly encountered uses of explicit garbage collection occurs with RMI's distributed garbage collection (DGC). Applications using RMI refer to objects in other virtual machines. Garbage can't be collected in these distributed applications without occasional local collection, so RMI forces periodic full collection. The frequency of these collections can be controlled with properties. For example, java -Dsun.rmi.dgc.client.gcInterval=3600000 specifies explicit collection once per hour instead of the default rate of once per minute. However, this may also cause some objects to take much longer to be reclaimed. These properties can be set as high as Long.MAX_VALUE to make the time between explicit collections effectively infinite, if there is no desire for an upper bound on the timeliness of DGC activity. The Solaris 8 Operating Environment supports an alternate version of libthread that binds threads to light-weight processes (LWPs) directly. Some applications can benefit greatly from the use of the alternate libthread. This is a potential benefit for any threaded application. To try this, set the environment variable LD_LIBRARY_PATH to include /usr/lib/lwp before launching the virtual machine. The alternate libthread is the default libthread in the Solaris 9 Operating Environment. Soft references are cleared less aggressively in the server virtual machine than the client. The rate of clearing can be slowed by increasing a parameter in this way: -XX:SoftRefLRUPolicyMSPerMB=10000. The default value is 1000, or one second per megabyte. 6 ConclusionGarbage collection can become a bottleneck in different applications depending on the requirements of the applications. By understanding the requirements of the application and the garbage collection options, it is possible to minimize the impact of garbage collection. 7 Other Documentation7.1 Example of OutputThe GC output examples document contains examples for different types of garbage collector behavior. The examples show the diagnostic output from the garbage collector and explain how to recognize various problems. Examples from different collectors are included. 7.2 Frequently Asked QuestionsA FAQ is included that contains answers to specific questions. The level of detail in the FAQ is generally greater than in this tuning document. February 01 小学生的想象力要求:把以下四句话用关联词连接 October 28 Part II: How to use JConsole接着前一篇Blog,现在JConsole已经可以启动了。而且JMX的配置方面也整理了一下。JConsole的具体使用界面上,有以下这样的一些截图: 连接上远端的JVM以后可以通过JConsole看到如下截图: 图1:“概述”界面 图2:“内存”界面 图3:“线程”界面 图4:“类”界面 图5:“VM 摘要”界面 图6:“MBean”界面 前面的5个标签页,主要通过图表的方式,将JVM的运行状况用图表的方式表示出来,可以看到内存,CPU,线程,类的概况,以及各个方面的详细图表情况,这样的图表方式可以非常方便的看到系统运行时的压力以及瓶颈在哪里。 第六张标签页显示了MBean的情况,MBean是JMX体系下的一种JavaBean,可以通过MBean所提供的方法,获取某个具体对象的运行情况,甚至可以得到一些对象的Dump数据。MBean非常的多,使用方法也比较麻烦,具体请参看下面的文章:Overview of Monitoring and Management. http://www.totodotnet.net/2007/08/10/part-ii-how-to-use-jconsole/ Part I: How to use JConsoleJConsole是一个JDK中提供的JVM监视与管理的工具,主要是通过JMX来提供监视与管理。 默认情况下,JVM是不启动JMX服务,并提供被监视与被管理的能力的,必须在启动Java程序之前,在Java [opt] [app]中指定JMX的服务。JConsole提供本地和远程的两种监管方式,远程又可以分为直接监视,另外一种是通过JMX的服务器来管理。 根据目前我的需要,我举一个很简单的远程监管例子。因为JConsole本身也要耗费一定的资源,所以用远程方式是比较推荐的。 首先启动JConsole: (因为在日文系统中,所以显示的为日文) 选择下面的Remote Access,输入host:portNumb的格式,另外输入用户名和密码,用户名和密码存储在<JAVA_HOME>/lib/management目录下,将jmxremote.password.template 复制为management.jmxremote.password(如果需要可以将文件的只读属性打开)。注意:这个文件是放在JRE的lib目录下。修改过以后的内容大致如下:
另外,默认情况下,SSL是被打开的,需要在被监视的机器上生成相应的SSL证书。在Java中可以使用keytool来生成,具体步骤如下:
其中第三条将需要你将第二步生成的CSR文件提交给VeriSign这样公司验证,然后返回给你一个可以使用CER证书,然后在Import,我们主要目的是为了体验JConsole,所以这一步我们就略过。所以我们设定不使用SSL,具体设置如下:
注意:这两行将使用非认证,非SSL的情况,在真实的服务器上要小心,很容易留下漏洞的。 在Windows系统下,如果你将Tomcat安装为服务模式,则可以在右下角Tray 图标中点击配置Tomcat,可以在例如下图的属性中配置,非常的简单: 如果不使用Windows系统,则需要在Catalina.bat中改写Java运行的参数。 改完了Tomcat的配置,启动Tomcat。 在远程机器上点击JConsole的连接即可。JConsole的具体使用以及分析下次继续。 ——————————————————- 方法1: 最简单的方式:不用密码,不用SSL
方法2: 使用密码,不用SSL
这两种方法是最简单的,并且第二种方法具有一定的安全性。具体可以参考Tomcat的文档:Monitoring http://www.totodotnet.net/2007/08/09/part-i-how-to-use-jconsole/ OutOfMemory:PermGen Space异常的处理和分析Java程序员没有遇到过OutOfMemory简直就是不可能的事情! 可见在Java的世界中,太多的不确定因素导致Java运行程序直接崩溃,直接抛出OutOfMemory异常,而一旦遇到了这个问题,调查起来就非常的困难。在JDK 5.0以前,OutOfMemory只有这么一句话: java.lang.OutOfMemory Exception…基本上无从下手,无从分析。从JDK 5.0以后对OutOfMemory增加了许多的详细说明,为这个异常的分析提供了很大的便利。 这次遇到的问题就是会抛出OutOfMemory:PermGen Space的异常,这个异常非常有意思,根据【此文章】的描述,这是一个Sun JVM的bug,从2003年开始,一只到现在都没有解决。而且提出来的解决方案是使用JRockit。Bug产生的原因已经找到,就是因为JVM在分配PermGen Space的时候出现了PermGen Space不足的情况,默认情况下 PermGen的大小为64M,在不换用JRockit的情况下,可以在启动JVM的时候添加一个参数: -XX: MaxPermSize= 128m| 256m| 512m。 那么究竟什么是PermGen呢? PermGen 原来是指Permanent Generation,本身是在Java的垃圾收集机制(GC)中产生的一个概念。Java的垃圾收集机制最早只是遍历所有的对象,如果发现某个对象没有被引用,则回收,这是在早期的Java 1.0和Java 1.1的时候的GC规则。慢慢的,这样一种“愚蠢的”GC算法成为了JVM性能的瓶颈,在拥有大量数据的Java应用程序中,GC的算法被高度强化,于是各种各样高效的JVM GC算法被发展了起来。从J2SE也就是Java 1.2开始,JVM引入了多种GC算法,其中一种用的非常多的就是Generational Collection,中文也叫做“分代收集法”。 分代收集法摈弃了对所有对象的遍历,而是采用一些经验属性去避免额外的工作(While naive garbage collection examines every live object in the heap, generational collection exploits several empirically observed properties of most applications to avoid extra work)。其中导入了一个非常关键的概念:infant mortality (幼儿死亡率),这表示越是新生成的变量或者对象,越容易被收集。下面一张图表示了对象的生命周期,横轴表示的是测试到对象的生命周期,纵轴表示在一个指定的生命周期上被回收的对象数量。 可以看到,在使用了分代收集法以后,年轻一代的对象被收集的比例最高。并且在内存中的对象会按照不同的“年龄”来划分,当一个年龄段的对象满了以后,在这个年龄段上就会发生垃圾收集,从最年轻的一代开始,一直到“永生代”,在内存中,所有的对象可以划分为很多代,最后的一代“永生代”就是“Permanent Generation”,这里就是直接引出“Permanent Generation”概念的地方。具体可以参考下图: 根据前面所说的情况,在分代垃圾收集的情况下会产生Permanent Generation的概念,而这个分代垃圾收集法是并行收集和并发收集的基础,所以Permanent Generation会一直存在,那么这个Permanent Generation究竟是做什么用的呢?这里保存了JVM中所有对象的类信息,包括类的元数据,还有方法描述等等,所以这一代内存垃圾收集算法是不一样的,在Java大程序的情况下,尤其是J2EE 或者说Java EE的大型应用程序上,Permanent Generation的大小会直接限定能载入类的数量和大小。 【解决办法】就是设定JVM启动的时候参数,可以如下设置:
另外PermSize 和MaxPermSize如果设置为相同还可以在一定程度上提高性能,因为,PermSize在不断的变化中会需要转移其中的数据。如果固定了以后,则可以减少每次扩大PermSize带来的性能损失。 更多的请参考 【Java官方站点】 另外,还可以在Java启动的时候添加下面的参数来看GC的运行情况:
(完) October 14 关掉自动更新重启提示(XP)Windows自动更新在完成后会不停的弹出需要重启的窗口,一不小心就会按错。 关掉这个讨厌的提示,而且不影响自动更新正常运行只需:开始,运行,sc stop wuauserv。 另一个方法是:开始,运行,gpedit.msc,计算机配置>管理模板>windows 组件>windows update>重新提示计划安装后的重新启动。选择启用,设置一个很长的时间。 来自LifeHack August 15 ASM 2.0 Bytecode Framework入门编写者:Eugene Kuleshov Java提供的动态类装载和反射使其成为了动态语言。但是在一些情况下,反射操作并没有多大意义,开发者需要从非Java源代码中生成bytecode,例如像Groovy(JSR-241)或者BeanShell(JSR-274)这样的脚本语言,或者从例如关系映射配置(OR-mapping configuration)这样的元数据(metadata)中生成bytecode。在和现存的类一起使用时,尤其是在源代码没有Java源代码的情况下,有些工具需要对相互依赖性或者方法进行静态分析、或者为了生成测试评估、检测bug和反模式。对于在Java5中新增加的特性,例如 annotation(注释)和generic(类属),它们都将影响bytecode的结构,并且也是那些用来保持bytecode良好的性能的 bytecode操作工具所应该特别关注的。本文将给出一个用于Java的、最小、最快的bytecode操作框架。 框架结构ASM bytecode操作框架使用Java语言编写并采用了基于访问者(visitor-based)的方式来生成bytecode、驱动现有类的变化。它使开发者能够避免直接处理类实例池和在方法bytecode中的位移,因此它为开发者隐藏掉了bytecode的复杂性并且提供了与其它工具(例如 BCEL, SERP, 或者 Javassist)相比更佳的性能。 为了提供灵活的捆绑,ASM被分割为以下几个package:
下面的一些章节将对ASM框架中的Core package进行介绍。为了更好地了解这个package的组织方式,你需要对定义在 JVM规范中的bytecode结构做一些基本的了解。这里提供了一个高层面的类文件格式图表(
这里我们需要注意以下几点:
正如你所见,对bytecode进行优化并非易事。而ASM框架降低了下层结构的复杂性并为访问bytecode信息进行复杂的变换提供了简化API。 基于事件的bytecode处理Core package使用一种推送的方式(与常用在 SAX API中的“Visitor”设计模式相似)来遍历复杂的bytecode结构。ASM定义了许多接口:例如 Core package能够被逻辑划分为以下两部分:
图-2展示了常见的生产者-消费者交互顺序图表
在上面的交互中,客户端应用创建 bytecode消费者将在一个“责任链”模式中被链接在一起:通过人工将事件委派给链中的下一个访问者、或者使用继承自
这个责任链能够被
在上面的代码中, 大多数访问方法都接受例如
请注意这些描述副正在使用一种“被擦除”的表示法,因为其中并不包括类属的信息。类属信息实际保存在一个分离的bytecode属性中,但ASM处理了这个属性并将类属签名字符串传入到相应访问方法中的一个
Util package包含了
截止到上面,我们已经谈了ASM框架的通用设计和对类结构的操作。但是最有趣的部分是ASM如何处理方法代码。 访问方法代码在ASM中,每个方法声明都通过 ? visitAnnotationDefault Visits the default value for annotation interface method * visitAnnotation Visits a method annotation * visitParameterAnnotation Visits a method parameter annotation * visitAttribute Visits a non-standard method attribute ? visitCode Starts the visit of the method's code for non-abstract and non-native methods *
值得注意的是 还需要注意的是如果一个方法实际上具有一些bytecode(例如它不是抽象的或者本地的方法),那么
另外一个对于任何一种bytecode生成物或者变化产物的挑战是在方法代码中的位移将会发生改变,因此在附加指令插入后或者从方法代码中删除指令时要修正位移值。这应用于所以跳转操作代码( 上面似乎听起来很复杂,因为这里需要读者具有对bytecode指令深入的了解。但是通过在被编译的类上使用 通过ASM 访问者跟踪类的依赖性目前已经有一些文章解释了如何使用ASM生成bytecode(见下面的资源)。这里我们就不再赘述了,下面让我们看一下如何使用ASM对现有的类进行分析吧。这是一个有趣的应用:它能够捕捉任何指定模块或者.jar文件的外部类或者package的信息。为了简化起见,这个示例只捕获、输出依赖性,而不跟踪依赖物的类型(例如父类、方法参数、本地变量类型等)。 请注意处于分析之目的,我们不需要为用于注释、字段、方法的子访问者创建新的实例。所有这些访问者,包括类、签名访问者都在下面的单一类中实现:
例如,我们将跟踪在package之间的依赖性,因此单独的类应该通过package名聚合在一起:
为了收集依赖性,例如 首先是 内部形式所用到的类名(父类、接口、异常、字段和方法拥有者);例如
在这个示例中, 另一个示例是类型描述符(注释、枚举、字段类型、新建数组指令的参数等);例如
方法描述符用在方法声明、调用指令描述参数类型和返回类型;例如
特殊的示例是用于一些"visit"方法中提供Java5类属信息的
实现
实现
现在我们能够使用
被收集的信息能够表示为多种方式。其中一种就是建立依赖树、计算一些度量值,或者创建一些可视化图表。例如,图-5以简单的Java2D代码展示了ant.1.6.5.jar 的依赖性信息图表 。下面的图表在水平方向展示了 input .jar的package信息、在垂直方向展示了外部依赖性。方块的颜色深度表示了package被引用的次数。
完整的代码将在ASM的下一个版本中给出。不过你也可以通过ASM CVS获取。 结论ASM2.0为开发者隐藏了一些bytecode的复杂性,它允许开发者在bytecode层高效地使用Java特性。本框架不但允许你变换、生成bytecode,而且还能提取出现有代码的重要细节。本API正在不断地改善中,2.0版本包含了J2SE5.0引入的类属和注释。在此之后,对Mustang(Java6.0)特性的支持已经被添加到了ASM框架中。 资源
引用:固定链接 Java SE 6 新特性: HTTP 增强chris 发表于 2007-08-15 08:04:58 摘要:Java SE 6 有着很多 HTTP 相关的新特性,使得 Java SE 平台本身对网络编程,尤其是基于 HTTP 协议的因特网编程,有了更加强大的支持。概述 import java.net.*; 当 Java 程序试图从一个要求认证的网站读取信息的时候,也就是说,从联系于 http://Protected.com 这个 URLConnection 的 InputStream 中 read 数据时,会引发 FileNotFoundException。尽管笔者认为,这个 Exception 的类型与实际错误发生的原因实在是相去甚远;但这个错误确实是由网络认证失败所导致的。 要解决这个问题,有两种方法: 其一,是给 URLConnection 设定一个“Authentication”属性: String credit = USERNAME + ":" + PASSWORD; 这里假设 http://PROTECTED.COM 使用了基本(Basic)认证类型。 从上面的例子,我们可以看出,设定 Authentication 属性还是比较复杂的:用户必须了解认证方式的细节,才能将用户名/密码以一定的规范给出,然后用特定的编码方式加以编码。Java 类库有没有提供一个封装了认证细节,只需要给出用户名/密码的工具呢? 这就是我们要介绍的另一种方法,使用 java.net.Authentication 类。 每当遇到网站需要认证的时候,HttpURLConnection 都会向 Authentication 类询问用户名和密码。 Authentication 类不会知道究竟用户应该使用哪个 username/password 那么用户如何向 Authentication 类提供自己的用户名和密码呢? 提供一个继承于 Authentication 的类,实现 getPasswordAuthentication 方法,在 PasswordAuthentication 中给出用户名和密码: class DefaultAuthenticator extends Authenticator {然后,将它设为默认的(全局)Authentication: Authenticator.setDefault (new DefaultAuthenticator()); 那么,不同的网站需要不同的用户名/密码又怎么办呢? Authentication 提供了关于认证发起者的足够多的信息,让继承类根据这些信息进行判断,在 getPasswordAuthentication 方法中给出了不同的认证信息: getRequestingHost() 另一件关于 Authentication 的重要问题是认证类型。不同的认证类型需要 Authentication 执行不同的协议。至 Java SE 6.0 为止,Authentication 支持的认证方式有: HTTP Basic authentication 这里我们着重介绍 NTLM。 NTLM 是 NT LAN Manager 的缩写。早期的 SMB 协议在网络上明文传输口令,这是很不安全的。微软随后提出了 WindowsNT 挑战/响应验证机制,即 NTLM。 NTLM 协议是这样的: ·客户端首先将用户的密码加密成为密码散列; ·客户端向服务器发送自己的用户名,这个用户名是用明文直接传输的; ·服务器产生一个 16 位的随机数字发送给客户端,作为一个 challenge(挑战) ; ·客户端用步骤1得到的密码散列来加密这个 challenge ,然后把这个返回给服务器; ·服务器把用户名、给客户端的 challenge 、客户端返回的 response 这三个东西,发送域控制器 ; ·域控制器用这个用户名在 SAM 密码管理库中找到这个用户的密码散列,然后使用这个密码散列来加密 challenge; ·域控制器比较两次加密的 challenge ,如果一样,那么认证成功; Java 6 以前的版本,是不支持 NTLM 认证的。用户若想使用 HttpConnection 连接到一个使用有 Windows 域保护的网站时,是无法通过 NTLM 认证的。另一种方法,是用户自己用 Socket 这样的底层单元实现整个协议过程,这无疑是十分复杂的。 终于,Java 6 的 Authentication 类提供了对 NTLM 的支持。使用十分方便,就像其他的认证协议一样: class DefaultAuthenticator extends Authenticator {这里,根据 Windows 域账户的命名规范,账户名为域名+”/”+域用户名。如果不想每生成 PasswordAuthentication 时,每次添加域名,可以设定一个系统变量名“http.auth.ntlm.domain“。 Java 6 中 Authentication 的另一个特性是认证协商。目前的服务器一般同时提供几种认证协议,根据客户端的不同能力,协商出一种认证方式。比如,IIS 服务器会同时提供 NTLM with kerberos 和 NTLM 两种认证方式,当客户端不支持 NTLM with kerberos 时,执行 NTLM 认证。 目前,Authentication 的默认协商次序是: GSS/SPNEGO -> Digest -> NTLM -> Basic 那么 kerberos 的位置究竟在哪里呢? 事实上,GSS/SPNEGO 以 JAAS 为基石,而后者实际上就是使用 kerberos 的。 轻量级 HTTP 服务器 Java 6 还提供了一个轻量级的纯 Java Http 服务器的实现。下面是一个简单的例子: public static void main(String[] args) throws Exception{然后,在浏览器中访问 http://localhost:7778/myapp/,我们得到: ![]() 图一 浏览器显示 首先,HttpServer 是从 HttpProvider 处得到的,这里我们使用了 JDK 6 提供的实现。用户也可以自行实现一个 HttpProvider 和相应的 HttpServer 实现。 其次,HttpServer 是有上下文(context)的概念的。比如,http://localhost:7778/myapp/ 中“/myapp/”就是相对于 HttpServer Root 的上下文。对于每个上下文,都有一个 HttpHandler 来接收 http 请求并给出回答。 最后,在 HttpHandler 给出具体回答之前,一般先要返回一个 Http head。这里使用 HttpExchange.sendResponseHeaders(int code, int length)。其中 code 是 Http 响应的返回值,比如那个著名的 404。length 指的是 response 的长度,以字节为单位。 Cookie 管理特性 Cookie 是 Web 应用当中非常常用的一种技术, 用于储存某些特定的用户信息。虽然,我们不能把一些特别敏感的信息存放在 Cookie 里面,但是,Cookie 依然可以帮助我们储存一些琐碎的信息,帮助 Web 用户在访问网页时获得更好的体验,例如个人的搜索参数,颜色偏好以及上次的访问时间等等。网络程序开发者可以利用 Cookie 来创建有状态的网络会话(Stateful Session)。 Cookie 的应用越来越普遍。在 Windows 里面,我们可以在“Documents And Settings”文件夹里面找到IE使用的 Cookie,假设用户名为 admin,那么在 admin 文件夹的 Cookies 文件夹里面,我们可以看到名为“admin@(domain)”的一些文件,其中的 domain 就是表示创建这些 Cookie 文件的网络域, 文件里面就储存着用户的一些信息。 JavaScript 等脚本语言对 Cookie 有着很不错的支持。 .NET 里面也有相关的类来支持开发者对 Cookie 的管理。 不过,在 Java SE 6 之前, Java一直都没有提供 Cookie 管理的功能。在 Java SE 5 里面, java.net 包里面有一个 CookieHandler 抽象类,不过并没有提供其他具体的实现。到了 Java SE 6, Cookie 相关的管理类在 Java 类库里面才得到了实现。有了这些 Cookie 相关支持的类,Java 开发者可以在服务器端编程中很好的操作 Cookie, 更好的支持 HTTP 相关应用,创建有状态的 HTTP 会话。 ·用 HttpCookie 代表 Cookie java.net.HttpCookie 类是 Java SE 6 新增的一个表示 HTTP Cookie 的新类, 其对象可以表示 Cookie 的内容, 可以支持所有三种 Cookie 规范: Netscape 草案 RFC 2109 - http://www.ietf.org/rfc/rfc2109.txt RFC 2965 - http://www.ietf.org/rfc/rfc2965.txt 这个类储存了 Cookie 的名称,路径,值,协议版本号,是否过期,网络域,最大生命期等等信息。 ·用 CookiePolicy 规定 Cookie 接受策略 java.net.CookiePolicy 接口可以规定 Cookie 的接受策略。 其中唯一的方法用来判断某一特定的 Cookie 是否能被某一特定的地址所接受。 这个类内置了 3 个实现的子类。一个类接受所有的 Cookie,另一个则拒绝所有,还有一个类则接受所有来自原地址的 Cookie。 ·用CookieStore 储存 Cookie java.net.CookieStore 接口负责储存和取出 Cookie。 当有 HTTP 请求的时候,它便储存那些被接受的 Cookie; 当有 HTTP 回应的时候,它便取出相应的 Cookie。 另外,当一个 Cookie 过期的时候,它还负责自动删去这个 Cookie。 ·用 CookieManger/CookieHandler 管理 Cookie java.net.CookieManager 是整个 Cookie 管理机制的核心,它是 CookieHandler 的默认实现子类。下图显示了整个 HTTP Cookie 管理机制的结构: ![]() 图 2. Cookie 管理类的关系 一个 CookieManager 里面有一个 CookieStore 和一个 CookiePolicy,分别负责储存 Cookie 和规定策略。用户可以指定两者,也可以使用系统默认的 CookieManger。 例子 下面这个简单的例子说明了 Cookie 相关的管理功能: // 创建一个默认的 CookieManager 其他新特性 ·NetworkInterface 的增强 从 Java SE 1.4 开始,JDK 当中出现了一个网络工具类 java.net.NetworkInterface,提供了一些网络的实用功能。 在 Java SE 6 当中,这个工具类得到了很大的加强,新增了很多实用的方法。例如: public boolean isUp() 用来判断网络接口是否启动并运行 public boolean isLoopback() 用来判断网络接口是否是环回接口(loopback) public boolean isPointToPoint() 用来判断网络接口是否是点对点(P2P)网络 public boolean supportsMulticast() 用来判断网络接口是否支持多播 public byte[] getHardwareAddress() 用来得到硬件地址(MAC) public int getMTU() 用来得到最大传输单位(MTU,Maximum Transmission Unit) public boolean isVirtual() 用来判断网络接口是否是虚饨涌? 关于此工具类的具体信息,请参考 Java SE 6 相应文档(见 参考资源)。 ·域名的国际化 在最近的一些 RFC 文档当中,规定 DNS 服务器可以解析除开 ASCII 以外的编码字符。有一个算法可以在这种情况下做 Unicode 与 ASCII 码之间的转换,实现域名的国际化。java.net.IDN 就是实现这个国际化域名转换的新类,IDN 是“国际化域名”的缩写(internationalized domain names)。这个类很简单,主要包括 4 个静态函数,做字符的转换。 结束语 Java SE 6 有着很多 HTTP 相关的新特性,使得 Java SE 平台本身对网络编程,尤其是基于 HTTP 协议的因特网编程,有了更加强大的支持。 本页页面地址: http://www.matrix.org.cn/resource/article/2007-08-15/HTTP_297e66f9-4ac3-11dc-8d96-bf0b98a1a3c8.html July 26 关于AspectJ 中的pointcut 语法(Z) 这两天忙着看AspectJ in Action 为了补一下AOP知识。看了Spring 2.0的规范,其中AOP部分已经基本融合了AspectJ,看来有必要看一看AspectJ了。
一元操作符:! 二元操作符:||和&& 优先权同java 2.签名语法 类型签名样式 主要的例子: Account 类型Account *Account 使用Account名称结束的类型,如SavingsAccount和CheckingAccount java.*.Date 类型Date在任何直接的java子包中,如java.util.Date和java.sql.Date java..* 任何在java包或者所有子包中的类型,如java.awt和java.util或者java.awt.event 和java.util.logging javax..*Model+ 所有javax包或者子包中以Model结尾的类型和其所有子类,如TableModel,TreeModel。 !vector 所有除了Vector的类型 Vector|| Hashtable Vector或者Hashtable类型 java.util.RandomAccess+ 实现RandomAccess和List的所有子类 && java.util.List+ 方法和构造器签名模式 public void Collection.clear(): 在Collection中同样签名的clear方法 public void Account.debit(float) throws InsufficientBalanceException: Account中同样签名的debit方法 public void Account.set*(*) Account中以set开头,并且只有一个参数类型的方法 public void Account.*() Account中所有的没有参数的public void 方法 public * Account.*() Account中所有没有参数的public 方法 public * Account.*(..) Account中所有的public 方法 * Account.*(..) Account中的所有方法,包括private方法 !public * Account.*(..) 所有的非public 方法 * Account+.*(..) 所有的方法,包括子类的方法 * java.io.Reader.read(..) 所有的read方法 * java.io.Reader.read(char[],..) 所有以read(char[])开始的方法,包括read(char[])和read(char[],int,int) * javax..*.add*Listener(EventListener+) 命名以add开始,以Listener结尾的方法,参数中为EventListener或子类 * *.*(..) throws RemoteException 抛出RemoteException的所有方法 构造器,同上面 public Account.new() 没有参数的构造器方法 属性签名模式 同方法一样,属性也查不多 * Account.* 所有的Account属性 !public static * banking..*.* 所有的非public static 属性,在banking的包或者子包中 3.主要的pointcuts类型 分类pointcuts 遵循特定的语法用于捕获每一个种类的可使用连接点。 主要的种类:
主要包括两种类型的控制流: cflow(Pointcut),捕获所有的连接点在指定的方法执行中,包括执行方法本身。 cflowbelow(Pointcut),捕获所有的连接点在指定的方法执行中,除了执行方法本身。 如以下的例子: cflow(call(* Account.debit(..)) 所有的debit方法中的连接点,包括debit方法本身 cflowbelow(call(* Account.debit(..)) 所有debit方法中的连接点,除了debit方法本身 cflow(transactedOperations()) 所有由transactedOperations捕获的连接点 cflowbelow(execution(Account.new(..)) 所有在Account 构造器中执行的连接点 基于词汇结构的连接点 源代码片断。,如within()和withincode() within :捕获在指定类或者方面中的程序体中的所有连接点,包括内部类。 Withincode:用于捕获在构造器或者方法中的所有连接点,包括在其中的本地类 执行对象连接点 匹配this,和target对象,作为方法被调用的对象。 this(Account),所有Account的实例的执行点,匹配所有的连接点,如方法调用,属性设置,当前的执行对象为Account,或者其子类。 target(Account):匹配所有的连接点,目标对象为Account或其子类。 必须执行相应的类型,不能使用*,或者..通配符。当前静态方法,不能被匹配。 在within()和this()中的区别: 一个是程序体,而另一个为对象执行。 参数pointcuts 用于捕获参数类型的连接点。 args(String,..,int) args(RemoteException) 条件检测pointcuts if(System.currentTimeMillis()>triggerTime) 基本的语法就这些,不过AspectJ5 已经增加了不少语法,主要关于Annotation 的,不过这部分还没有仔细研究,以后再讲解吧。希望能有所帮助 June 06 一个成年男子的暴笑日记(Z)我知道我不算帅哥,但曾经有人看我满月的照片时,也说过我左边的鼻孔很偶像派。 March 21 log4j配置文件格式(Z) 在实际编程时,要使Log4j真正在系统中运行事先还要对配置文件进行定义。定义步骤就是对Logger、Appender及Layout的分别使用。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是java properties(key=value)【Java特性文件(键=值)】。(这里只说明properties文件)
1、配置根Logger 其语法为: 2、配置日志信息输出目的地 其语法为: 3、配置日志信息的格式 其语法为: March 15 Linux网络资源这是某位大大总结的好东东,网上看见,收藏了!
gearbox
2004-07-28, 00:56 CODE 第一部分:Linux基础应用
1、《Linux从入门到精通》
http://www.gouhuo.com/study/linuxbook.zip 2、 Linux 系统安全与优化中文版
这本书的英文版“Get Acquainted with Linux Security and Optimization System”(简称LinuxSOS)是Linux文档计划(Linux Document Project)中比较新的一本指南。这本书不是Linux的入门书籍,读这本书需要有Linux或者Unix的背景知识。如果你已经安装过Linux而且能够使用一些简单的Unix命令,那么这本书会对你有很大的帮助。 http://www.linuxaid.com.cn/download/training/linuxsos-cn.pdf 3、Linux安装与配置简明手册 13-Aug-2002 16:14 20M
http://cpss.zz.ha.cn/study/linux/Linux%b0%b2%d7%b0%d3%eb%c5%e4%d6%c3%bc%f2%c3%f7%ca%d6%b2%e1.zip 4、Linux编程白皮书.zip 13-Aug-2002 16:14 16M
http://cpss.zz.ha.cn/study/linux/Linux%b1%e0%b3%cc%b0%d7%c6%a4%ca%e9.zip 5、Linux网站建设技术指南 13-Aug-2002 16:14 9.2M
http://cpss.zz.ha.cn/study/linux/Linux%cd%f8%d5%be%bd%a8%c9%e8%bc%bc%ca%f5%d6%b8%c4%cf.zip 6、Linux系统分析与高级编程 13-Aug-2002 16:14 11M
http://cpss.zz.ha.cn/study/linux/Linux%cf%b5%cd%b3%b7%d6%ce%f6%d3%eb%b8%df%bc%b6%b1%e0%b3%cc%bc%bc%c a%f5.zip 7、Linux系统管理白皮书.zip 13-Aug-2002 16:14 6.8M
http://cpss.zz.ha.cn/study/linux/Linux%cf%b5%cd%b3%b9%dc%c0%ed%b0%d7%c6%a4%ca%e9.zip 8、Linux应用程序开发指南 13-Aug-2002 16:14 9.1M
http://cpss.zz.ha.cn/study/linux/Linux%d3%a6%d3%c3%b3%cc%d0%f2%bf%aa%b7%a2%d6%b8%c4%cf%a3%ba%ca%b9%d 3%c3Gtk+%20Gnome%bf%e2.zip 9、Linux 24学时教程.zip 13-Aug-2002 16:14 34M
http://cpss.zz.ha.cn/study/linux/Linux%2024%d1%a7%ca%b1%bd%cc%b3%cc.zip 10、Red Hat Linux 6大全.zip 13-Aug-2002 16:15 33M
http://cpss.zz.ha.cn/study/linux/Red%20Hat%20Linux%206%b4%f3%c8%ab.zip 11、Red Hat Linux 6管理工具 13-Aug-2002 16:15 13M
http://cpss.zz.ha.cn/study/linux/Red%20Hat%20Linux%206%b9%dc%c0%ed%b9%a4%be%df.zip 12、http://www.linuxsir.org/pdf/ebook1.rar
http://www.linuxsir.org/pdf/ebook2.rar 具体文章如下: 基础建设讨论专版: Linux管理员手册 linux入门教程 linux指令大全 红旗版区的:
红旗桌面4正式版最新使用方法和问题解答100例 Linux shell进阶应用与shell编程
命令大集合 TCSH shell 编程 Bourne Shell及shell编程 Linux Shell简介 脚本精华欣赏 使用 Bash shell 脚本进行功能测试 Linux 发行版SuSE专题
SuSE 解决方案 13、Debian的中文FAQ 600k pdf
http://linuxdoc.51.net/download/Debian_cn_FAQ.pdf 14、Linux Kernel 核心手册(中文)552k zip
http://linuxdoc.51.net/download/Linux_Kernel_cn.zip 15、Linux + Solaris 48k pdf
http://linuxdoc.51.net/download/LinuxSolaris.pdf 16、Linux SOS 1.1 1.3M pdf
http://linuxdoc.51.net/download/linuxsos-11.pdf 17、SuSE官方汉化手册 1.4M pdf
http://linuxdoc.51.net/download/suse_guanfang_hanhua.pdf 18、Linux Kernel 1.3M pdf
http://linuxdoc.51.net/download/linux_kernel.pdf 19、Linux程序员指南 337k zip
http://linuxdoc.51.net/download/linux_program.zip 20、Linux高级技巧集 72k zip
http://linuxdoc.51.net/download/linux_gaoji_jiqiao.zip 21、OReilly Unix超级工具(第三版)
http://bbs.itebook.net/attachment.php?aid=621 http://bbs.itebook.net/attachment.php?aid=622 22、FreeBSD使用大全(Chm格式)
是王波写的一本专门介绍Freebsd的书籍,共94章,图文并茂,是不可多得的FreeBSD方面的教材。 http://www.linuxdby.com/downloadlink.php?id=15 23、Redhat 9.0 官方中文安装指南
http://www.fcitx.org/flysail/rhl-ig-x86-zh_CN-9.tar.gz Redhat 9.0 官方中文入门指南
http://www.fcitx.org/flysail/rhl-gsg-zh_CN-9.tar.gz Redhat 9.0 官方中文定制指南
http://www.fcitx.org/flysail/rhl-cg-zh_CN-9.tar.gz 24、《Linux 新手管理员指南》
本书《Linux 新手管理员指南》是英文版LINUX NEWBIE ADMINISTRATOR GUIDE 的完整中文译本,共237页,PDF格式。 原版:http://linux-newbie.sunsite.dk/ 下载:http://www.linuxdby.com/downloadlink.php?id=51 25、Linux高级配置详解(PDG)
讲述在Linux操作系统下的软、硬件配置、网络应用配置、X Window系统配置以及内核的配置和编译等知识。 http://www.mycodes.net/down.asp?id=793&no=1 http://www.mycodes.net/down.asp?id=793&no=2 gearbox
2004-07-28, 00:58 QUOTE 第二部分:Linux系统管理
1、Setting up a Local Area Network (EN)上载:5/9/2002
http://www.joyfire.net/compress/rh-lan.pdf 2、linux for mainframe (EN)上载:5/9/2002
http://www.joyfire.net/compress/linux4mainframe.zip 3、Linux Consultants Guide (EN)上载:1/9/2002
http://www.joyfire.net/compress/Consultant...ide.html.tar.gz 4、LPI认证复习资料1 2 3 4 5 6 7 8上载:13/7/2002
http://www.joyfire.net/compress/l-lpi1.zip http://www.joyfire.net/compress/l-lpi2.zip http://www.joyfire.net/compress/l-lpi3.zip http://www.joyfire.net/compress/l-lpi4.zip http://www.joyfire.net/compress/l-lpi5.zip http://www.joyfire.net/compress/l-lpi6.zip http://www.joyfire.net/compress/l-lpi7.zip http://www.joyfire.net/compress/l-lpi8.zip 5、Red Hat Network Basic User Reference Guide (EN)上载:13/7/2002
http://www.joyfire.net/compress/rhn-basic-urg-en-3.3.tgz 6、Red Hat Network Enterprise User Reference Guide (EN)上载:13/7/2002
http://www.joyfire.net/compress/rhn-enterp...-urg-en-1.1.tgz 7、Linux FAQ 在线浏览 上载:11/6/2002
http://www.joyfire.net/compress/Linux-FAQ.html.tar.gz http://www.joyfire.net/Linux-FAQ/index.html 8、Linux系统分析与高级编程技术上载:4/5/2002
http://www.joyfire.net/compress/linux_adva..._technology.zip 9、RedHat Linux网络管理工具上载:4/5/2002
http://www.joyfire.net/compress/RadHat_Lin...nt_Tools_CN.zip 10、Linux管理指南上载:4/5/2002
http://www.joyfire.net/compress/Linux_Management_CN.zip 11、GNU Linux 高级网络应用服务指南上载:4/5/2002
http://www.joyfire.net/compress/GNU_linux_...twork_Guide.zip l 12、inux环境数据库管理员手册上载:4/5/2002 http://www.joyfire.net/compress/Linuxdb.zip 13、Complete Linux Command Reference (EN)上载:4/5/2002
http://www.joyfire.net/compress/Complete_L...d_Reference.zip 14、Bugzilla-Guide (EN) 上载:20/4/2002
http://www.joyfire.net/compress/Bugzilla-Guide.html.tar.gz 15、Llinuxcookbook (EN) 在线浏览 上载:20/4/2002
http://www.joyfire.net/compress/linuxcookb...1.2.html.tar.gz http://www.joyfire.net/linuxcookbook/index.html 16、Linux HOWTO (EN)(9.8M) 在线浏览 中文版和miniHOWTO (EN) 中文版上载:13/3/2002
http://www.joyfire.net/compress/Linux-html-HOWTOs.tar.gz http://www.joyfire.net/HOWTO/HOWTO-INDEX/howtos.html http://www.joyfire.net/compress/newhowto_cn.zip http://www.joyfire.net/compress/Linux-mini...20020420.tar.gz http://www.joyfire.net/compress/minihow_cn.zip 17、Advanced Bash-Scripting Guide(EN) 在线浏览 上载:11/3/2002
http://www.joyfire.net/compress/abs-guide.html.tar.gz http://www.joyfire.net/abs-guid/index.html 18、Securing and Optimizing Linux RedHat Edition -A Hands on Guide(EN) 在线浏览 上载:11/3/2002
http://www.joyfire.net/compress/Securing-O...1.3.html.tar.gz http://www.joyfire.net/solrhe/Securing-Opt...v1.3/index.html 19、CVS Best Practices(EN) 在线浏览 上载:11/3/2002
http://www.joyfire.net/compress/CVS-BestPr...ces.html.tar.gz http://www.joyfire.net/CVS-BestPractices/index.html 20、The Linux System Administrators' Guide(EN) 在线浏览 中文版上载:1/1/2002。
http://www.joyfire.net/compress/sag.html.tar.gz http://www.joyfire.net/sag/index.html http://www.joyfire.net/compress/Linuxsys.zip 21、The Linux Network Administrator's Guide, 2e (EN) 在线浏览 上载:1/1/2002
http://www.joyfire.net/compress/nag-2.0.html.tar.gz http://www.joyfire.net/nag2/index.html 22、Linux System Administration Made Easy (EN) 在线浏览 上载:1/1/2002
http://www.joyfire.net/compress/lame.html.tar.gz http://www.joyfire.net/lame/index.html 23、AKA讲座(a link)上载:1/1/2002
http://bj.aka.org.cn/Lectures/index.html 24、ORACLE for linux install handbook (EN)上载:1/1/2002 http://www.joyfire.net/compress/installguide_linu October 25 [转]三言二拍:实名这档子事很多人说,管理是门艺术,这是瞎扯。最简单、最直接的管理,别说艺术,连技术都算不上,勉强可以说是算术——算计的算,盘算的算,清算的算,秋后算账的算。 校园BBS上经常有些情绪帖,还找不到发帖人,让领导很是头痛——这很简单,实名,禁止校外IP发帖;手机短信经常出现诈骗、传递非法信息等问题,还找不到机主,让领导很是头痛——这很简单,实名,一卡对一人;blog猛不丁就有了1000多万用户,七嘴八舌,想说啥说啥,让领导很是头痛——这很简单,实名,一萝卜一坑。 实名,说白了,就是让你时时刻刻记得,老大哥炯炯的目光一直在背后盯着你。你是坏人,是暴民,是潜在的罪犯,但你什么坏事儿都不敢干。就像监考老师目不转睛地盯着你,就算你有作弊的心,恐怕也没作弊的胆。这叫威慑力,出门都怕被树叶砸破头的升斗小民,哪抗得住这阵势,早被威慑得只剩筛糠的份了。 有人说,你不干坏事,怕实名作甚?说这种话的,纯属猪头。这种人可能已经习惯了一天到晚有人盯梢,习惯了在自家做个爱都有摄像头监视着,习惯了腹诽几句领导都会被蛔虫给汇报了。 互联网协会秘书长黄澄清说:中国互联网协会博客研究小组建议的博客实名制是有限实名、后台实名,即网民在向网站提供信息登记开设博客时使用实名,在博客写作中仍可使用网名。貌似很温婉,很宽宏大量。言外之意,除了我,仍然没人知道你是一条狗,别怕。废话,怕的就是你。 中国人把有限的钱,都花在这种管理算术上,难怪在推动社会进步的技术上,总也没什么创新。 September 27 BlogThisSong在BlogThisSong.com,你可以:
(Publish by Windows Live Writer :P ) August 14 Windows Live Writer测试 |
|
|