当前位置: 首页 > news >正文

专业定制网吧桌椅seo工具箱

专业定制网吧桌椅,seo工具箱,小型企业网站建设,浙江柏臻软装设计有限公司调用栈里的引用类型数据是GC的根集合#xff08;root set#xff09;的重要组成部分#xff1b;找出栈上的引用是GC的根枚举#xff08;root enumeration#xff09;中不可或缺的一环。 要看JVM选择用什么方式。通常这个选择会影响到GC的实现。 如果JVM选择不记录任何这种…调用栈里的引用类型数据是GC的根集合root set的重要组成部分找出栈上的引用是GC的根枚举root enumeration中不可或缺的一环。 要看JVM选择用什么方式。通常这个选择会影响到GC的实现。 如果JVM选择不记录任何这种类型的数据那么它就无法区分内存里某个位置上的数据到底应该解读为引用类型还是整型还是别的什么。这种条件下实现出来的GC就会是“[b]保守式GCconservative GC[/b]”。在进行GC的时候JVM开始从一些已知位置例如说JVM栈开始扫描内存扫描的时候每看到一个数字就看看它“像不像是一个指向GC堆中的指针”。这里会涉及上下边界检查GC堆的上下界是已知的、对齐检查通常分配空间的时候会有对齐要求假如说是4字节对齐那么不能被4整除的数字就肯定不是指针之类的。然后递归的这么扫描出去。 保守式GC的好处是相对来说实现简单些而且可以方便的用在对GC没有特别支持的编程语言里提供自动内存管理功能。[urlhttp://www.hpl.hp.com/personal/Hans_Boehm/gc/]Boehm-Demers-Weiser GC[/url]是保守式GC中的典型代表可以嵌入到C或C等语言写的程序中。 小历史故事 微软的JScript和早期版VBScript也是用保守式GC的微软的JVM也是。VBScript后来改回用引用计数了。而微软JVM的后代也就是.NET里的CLR则改用了完全准确式GC。 为了赶上在一个会议上发布消息微软最初的JVM原型只有一个月左右的时间从开工到达到符合Java标准。所以只好先用简单的办法来实现也就自然选用了保守式GC。 信息来源[urlchannel9.msdn.com/Shows/BehindTheCode/Patrick-Dussud-Managing-Garbage-Collection]Patrick Dussud在Channel 9的访谈23分钟左右[/url] 保守式GC的缺点有 1、会有部分对象本来应该已经死了但有疑似指针指向它们使它们逃过GC的收集。这对程序语义来说是安全的因为所有应该活着的对象都会是活的但对内存占用量来说就不是件好事总会有一些已经不需要的数据还占用着GC堆空间。具体实现可以通过一些调节来让这种无用对象的比例少一些可以缓解但不能根治内存占用量大的问题。 2、由于不知道疑似指针是否真的是指针所以它们的值都不能改写移动对象就意味着要修正指针。换言之对象就不可移动了。有一种办法可以在使用保守式GC的同时支持对象的移动那就是增加一个间接层不直接通过指针来实现引用而是添加一层“句柄”handle在中间所有引用先指到一个句柄表里再从句柄表找到实际对象。这样要移动对象的话只要修改句柄表里的内容即可。但是这样的话引用的访问速度就降低了。Sun JDK的Classic VM用过这种全handle的设计但效果实在算不上好。 由于JVM要支持丰富的反射功能本来就需要让对象能了解自身的结构而这种信息GC也可以利用上所以很少有JVM会用完全保守式的GC。除非真的是特别懒… JVM可以选择在栈上不记录类型信息而在对象上记录类型信息。这样的话扫描栈的时候仍然会跟上面说的过程一样但扫描到GC堆内的对象时因为对象带有足够类型信息了JVM就能够判断出在该对象内什么位置的数据是引用类型了。这种是“[b]半保守式GC[/b]”也称为“根上保守conservative with respect to the roots”。 为了支持半保守式GC运行时需要在对象上带有足够的元数据。如果是JVM的话这些数据可能在类加载器或者对象模型的模块里计算得到但不需要JIT编译器的特别支持。 前面提到了Boehm GC实际上它不但支持完全保守的方式也可以支持半保守的方式。[urlgcc.gnu.org/java/]GCJ[/url]和[urlhttp://www.mono-project.com/]Mono[/url]都是以半保守方式使用Boehm GC的例子。 Google Android的Dalvik VM的早期版本也是使用半保守式GC的一个例子。不过到2009年中的时候Dalvik VM的内部版本就已经开始支持准确式GC了——[urlhttp://osdir.com/ml/android-platform/2009-06/msg00024.html]代价是优化过的DEX文件的体积膨胀了约9%[/url]。 其实许多较老的JVM都选择这种实现方式。 由于半保守式GC在堆内部的数据是准确的所以它可以在直接使用指针来实现引用的条件下支持部分对象的移动方法是只将保守扫描能直接扫到的对象设置为不可移动pinned而从它们出发再扫描到的对象就可以移动了。 完全保守的GC通常使用不移动对象的算法例如mark-sweep。半保守方式的GC既可以使用mark-sweep也可以使用移动部分对象的算法例如[urlhttp://www.cs.cornell.edu/home/fms/mcc/bartlett.html]Bartlett风格的mostly-copying GC[/url]。 半保守式GC对JNI方法调用的支持会比较容易管它是不是JNI方法调用是栈都扫过去…完事了。不需要对引用做任何额外的处理。当然代价跟完全保守式一样会有“疑似指针”的问题。 与保守式GC相对的是“[b]准确式GC[/b]”原文可以是precise GC、exact GC、accurate GC或者type accurate GC。外国人也挺麻烦的“准确”都统一不到一个词上⋯ 是什么东西“准确”呢关键就是“类型”也就是说给定某个位置上的某块数据要能知道它的准确类型是什么这样才可以合理地解读数据的含义GC所关心的含义就是“这块数据是不是指针”。 要实现这样的GCJVM就要能够判断出所有位置上的数据是不是指向GC堆里的引用包括活动记录栈寄存器里的数据。 有几种办法 1、让数据自身带上标记tag。这种做法在JVM里不常见但在别的一些语言实现里有体现。就不详细介绍了。打标记的方式在半保守式GC中倒是更常见一些例如CRuby就是用打标记的半保守式GC。CLDC-HI比较有趣栈上对每个slot都配对一个字长的tag来说明它的类型通过这种方式来减少stack map的开销类似的实现在别的地方没怎么见过大家一般都不这么取舍。 2、让编译器为每个方法生成特别的扫描代码。我还没见过JVM实现里这么做的虽说在别的语言实现里有见过。 3、从外部记录下类型信息存成映射表。现在三种主流的高性能JVM实现HotSpot、JRockit和J9都是这样做的。其中HotSpot把这样的数据结构叫做OopMapJRockit里叫做livemapJ9里叫做GC map。Apache Harmony的DRLVM也把它叫[urlhttp://svn.apache.org/viewvc/harmony/enhanced/java/trunk/drlvm/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp?viewmarkup]GCMap[/url]。 要实现这种功能需要虚拟机里的解释器和JIT编译器都有相应的支持由它们来生成足够的元数据提供给GC。 使用这样的映射表一般有两种方式 1、每次都遍历原始的映射表循环的一个个偏移量扫描过去这种用法也叫“解释式” 2、为每个映射表生成一块定制的扫描代码想像扫描映射表的循环被展开的样子以后每次要用映射表就直接执行生成的扫描代码这种用法也叫“编译式”。 在HotSpot中对象的类型信息里有记录自己的OopMap记录了在该类型的对象内什么偏移量上是什么类型的数据。所以从对象开始向外的扫描可以是准确的这些数据是在类加载过程中计算得到的。 每个被JIT编译过后的方法也会在[b]一些特定的位置[/b]记录下OopMap记录了执行到该方法的某条指令的时候栈上和寄存器里哪些位置是引用。这样GC在扫描栈的时候就会查询这些OopMap就知道哪里是引用了。这些特定的位置主要在 1、循环的末尾 2、方法临返回前 / 调用方法的call指令后 3、可能抛异常的位置 这种位置被称为[b]“安全点”safepoint[/b]。之所以要选择一些特定的位置来记录OopMap是因为如果对每条指令的位置都记录OopMap的话这些记录就会比较大那么空间开销会显得不值得。选用一些比较关键的点来记录就能有效的缩小需要记录的数据量但仍然能达到区分引用的目的。因为这样HotSpot中GC不是在任意位置都可以进入而只能在safepoint处进入。 而仍然在解释器中执行的方法则可以通过解释器里的功能自动生成出OopMap出来给GC用。 平时这些OopMap都是压缩了存在内存里的在GC的时候才按需解压出来使用。 HotSpot是用“解释式”的方式来使用OopMap的每次都循环变量里面的项来扫描对应的偏移量。 对Java线程中的JNI方法它们既不是由JVM里的解释器执行的也不是由JVM的JIT编译器生成的所以会缺少OopMap信息。那么GC碰到这样的栈帧该如何维持准确性呢 HotSpot的解决方法是所有经过JNI调用边界调用JNI方法传入的参数、从JNI方法传回的返回值的引用都必须用“句柄”handle包装起来。JNI需要调用Java API的时候也必须自己用句柄包装指针。在这种实现中JNI方法里写的“jobject”实际上不是直接指向对象的指针而是先指向一个句柄通过句柄才能间接访问到对象。这样在扫描到JNI方法的时候就不需要扫描它的栈帧了——只要扫描句柄表就可以得到所有从JNI方法能访问到的GC堆里的对象。 但这也就意味着调用JNI方法会有句柄的包装/拆包装的开销是导致JNI方法的调用比较慢的原因之一。[/quote] [sizemedium][b]实现例子Oracle/Sun HotSpot VM[/b][/size] Sun HotSpot VM从[urlhttp://java.sun.com/developer/technicalArticles/Networking/HotSpot/]设计之初[/url]就使用准确式GC。 在HotSpot VM之前Sun在1.0.x到1.2.x中提供的JVM后来称为Classic VM用的是半保守式的设计。在SPARC版JDK 1.2.1和1.2.2中提供的[urlhttp://labs.oracle.com/techrep/1998/abstract-67.html]EVM[/url]也称为ExactVM则实现了准确式GC。 后面举的一些例子也都显示高性能VM实现更倾向使用准确式GC即便一开始为了快速开发使用了半保守式GC后续发展为了追求性能也会渐渐朝着准确式的方向发展。 简要回答里已经提到了HotSpot的实现方式。下面引用几篇论文分别看看HotSpot的client编译器JDK6与server编译器对OopMap / safepoint的支持。 [urlhttp://www.ssw.uni-linz.ac.at/Research/Papers/Ko08/Ko08.pdf]Design of the Java HotSpot Client Compiler for Java 6[/url] [quote]The Java HotSpotTM VM also provides various other garbage collectors [Sun Microsystems, Inc. 2006c]. Parallel garbage collectors for server machines with large physical memories and multiple CPUs distribute the work among multiple threads, thus decreasing the garbage collection overhead and increasing the application throughput. A concurrent mark-and-sweep algorithm [Boehm et al. 1991; Printezis and Detlefs 2000] allows the user program to continue its execution while dead objects are reclaimed. Exact garbage collection requires information about pointers to heap objects. For machine code, this information is contained in object maps (also called oop maps) created by the JIT compiler. Besides, the compiler creates debugging information that maps the state of a compiled method back to the state of the interpreter. This enables aggressive compiler optimizations, because the VM can deoptimize [Holzle et al. 1992] back to a safe state when the assumptions under which an optimization was performed are invalidated (see Section 2.6). The machine code, the object maps, and the debugging information are stored together in a so-called native method object. Garbage collection and deoptimization are allowed to occur only at some discrete points in the program, called [i][b]safepoints[/b][/i], such as backward branches, method calls, return instructions, and operations that may throw an exception. … After register allocation, machine code can be generated in a rather simple and straightforward way. The compiler traverses the LIR, operation by operation, and emits appropriate machine instructions into a code buffer. This process also yields object maps and debugging information.[/quote] A Compiler for the Java HotSpot Virtual Machine 描述的是2000年JDK 1.3.0里的HotSpot Client Compiler [quote]4.5 Debug Information The back end generates [i]debug information[/i] as a side effect of code generation. Debug information includes a mapping of program counter offsets to bytecode indices, so-called pc-maps. It also includes oop maps (i.e., pointer maps), specifying the exact stack location of all oops for all pc’s where GC can occur. Finally, it includes safepoint information, which is used for GC as well. Pc-maps are required for exception handling: if a runtime exception occurs, the pc where the exception occurred is mapped to the corresponding bytecode index (bci). This bci is used to loop upi the exception handler. Oop maps are bit maps specifying which stack and register locations hold oops for a given pc. During GC, these locations need to be visited since they represent roots for GC. Also, if GC moves objects, pointers must be updated. GC cannot happen at arbitrary places, but only at safepoints. Safepoints are designated places in the code, usually function calls, backward branches, and return instructions. All threads running code (interpreted or compiled) must be suspended at a safepoint before GC is executed. At a safepoint, the location of all oops on the stack is known. The safepoint suspension mechanism is independent of the compiler. Its discussion is beyond the scope of this paper. Debug information is stored in a compressed form together with the generated code in [i]native method objects[/i]. They reside in the [i]code cache[/i] managed by the VM.[/quote] [urlhttp://www.usenix.org/events/jvm01/full_papers/paleczny/paleczny.pdf]The Java HotSpot Server Compiler[/url] [quote]15.Cleanup … Then we gather and output the information necessary for garbage collection. This includes the location of all object pointers which are alive across a safepoint, as well as the location of all values which are callee saves in the method, and all necessary computation information for derived pointers which have an object pointer as their base. … 17.Code Generation In addition to executable machine code, the code generator also provides oopmaps, debug info, exception tables, relocation information, and an implicit−null check table for use by the runtime system. All of this information is associated with one or more native-code offsets from method entry. Oopmaps and debug info are associated with the offset to their safepoint. Oopmaps are generated during register allocation and the code generator simply packages this information for the runtime. Safepoints at which a deoptimization may occur also record debug info describing either the constant value or native storage location for monitors, locals, and expression stack entries. The storage location may be a register or a stack frame offset. …[/quote] 在实际代码中生成OopMap的逻辑在Compile::BuildOopMaps()实现hotspot/src/share/vm/opto/buildOopMap.cpp 我的草稿箱里有一些关于HotSpot的client和server编译器分别如何生成OopMap的笔记不过还没整理完所以暂时就不放出来了。不过各位同学如果对此感兴趣的话可以从[urlhttp://hllvm.group.iteye.com/group/topic/21769]-XX:PrintAssembly[/url]输出的日志入手来了解OopMap会关联在哪些位置上里面的内容有些什么。知道了如何解读OopMap的信息就能很方便的知道一个被JIT编译过的方法会如何跟GC交互了某些局部变量是否需要显式置null也会一目了然。 例如说 [Verified Entry Point] 0x00007f3749ea3400: mov %eax,-0x6000(%rsp) … 0x00007f3749ea3453: callq 0x00007f3749e7c820 ; OopMap{[0]Oop off88} ;*invokevirtual intern ; - TestC2OopMapGeneration::doTest19 (line 4) ; {optimized virtual_call} 0x00007f3749ea3458: inc %ebp ;*iinc 这段输出含有一条x86-64的callq指令用来实现对intern()方法的调用。在后面的注释当中可以看到 OopMap{[0]Oop off88} 它的意思是 有一个OopMap与这条callq指令之后的一条指令inc %ebp关联在一起 在该指令位置上只有一个活跃的引用在栈顶上。 这是怎么解读的呢 OopMap记录输出的日志的构成是 OopMap{零到多个“数据位置内容类型”的记录 off该OopMap关联的指令的位置} 在这个例子中 [0]表示栈顶指针偏移量0这里就是[rsp 0]也就是栈顶右边的Oop说明这个位置存着一个普通对象指针ordinary object pointerHotSpot将指向GC堆中对象开头位置的指针称为Oop。 除了Oop之外可能出现的类型有 hotspot/src/share/vm/compiler/oopMap.hpp enum oop_types { // must fit in type_bits unused_value 0, // powers of 2, for masking OopMapStream oop_value 1, value_value 2, narrowoop_value 4, callee_saved_value 8, derived_oop_value 16 }; 对应的显示为 hotspot/src/share/vm/compiler/oopMap.cpp staticvoid print_register_type(OopMapValue::oop_types x, VMReg optional, outputStream* st) { switch( x ) { case OopMapValue::oop_value: st-print(“Oop”); break; case OopMapValue::value_value: st-print(“Value” ); break; case OopMapValue::narrowoop_value: tty-print(“NarrowOop” ); break; case OopMapValue::callee_saved_value: st-print(“Callers_” ); optional-print_on(st); break; case OopMapValue::derived_oop_value: st-print(“Derived_oop_” ); optional-print_on(st); break; default: ShouldNotReachHere(); }} off88就是这个OopMap记录关联的指令在方法的指令流中的偏移量这个数字是十进制的。 可以看到该方法的指令流是从地址0x00007f3749ea3400开始的十进制的88就是十六进制的0x58 0x00007f3749ea3400 0x58 0x00007f3749ea3458正好就是例子中callq指令后的inc %ebp所在的位置。 再举几个例子。 OopMap{off228} 这个记录比较简单。它说明在该方法的指令流中有一个OopMap与偏移量228的位置上的指令关联在一起。 该OopMap显示这个位置上没有任何活着的引用。 OopMap{rbpOop off144} 在偏移量为144的指令上关联了一个OopMap的记录有一个活跃的引用在寄存器RBP里。 OopMap{rbpNarrowOop off248} 在偏移量为248的指令上关联了一个OopMap的记录有一个活跃的引用在寄存器RBP里并且这个引用是压缩过的NarrowOop。 OopMap{[296]Callers_eax [292]Callers_ecx [288]Callers_edx [284]Callers_ebx [272]Callers_esi [268]Callers_edi [28]Callers_xmm0 [32]Callers_xmm0 [36]Callers_xmm1 [40]Callers_xmm1 [44]Callers_xmm2 [48]Callers_xmm2 [52]Callers_xmm3 [56]Callers_xmm3 [60]Callers_xmm4 [64]Callers_xmm4 [68]Callers_xmm5 [72]Callers_xmm5 [76]Callers_xmm6 [80]Callers_xmm6 [84]Callers_xmm7 [88]Callers_xmm7 off674} 这个OopMap记录看起来比较壮观。其实是它关联的指令位置上正好所有的callee-save的寄存器都保存到栈上了而已。例如说在[栈顶296]位置上保存的是调用方的eax至于它到底是不是一个Oop就得看调用方对应的OopMap是怎么说的了。 OopMap{[24]Oop [28]Derived_oop_[24] [32]Derived_oop_[24] off192} 这里可以看到derived oop类型的数据在栈上[28]位置的是由栈上[24]开始的一个对象的派生引用。 [sizemedium][b]实现例子IBM Sovereign JVM[/b][/size] IBM在JDK 5之前主要提供的JVM是Sovereign VM里面的GC是半保守式的栈上保守堆上准确而从JDK 5开始主要提供J9 VM里面的GC转为准确式。 关于IBM DK for Java 1.4.1中的Sovereign JVM所使用的半保守式GC设计可以参考下面这段文字 [urlhttp://download.boulder.ibm.com/ibmdl/pub/software/dw/jdk/diagnosis/GCandMemory-042005.pdf]IBM JVM Garbage Collection and Storage Allocation techniques[/url] [quote]4.1 Mark Phase In this phase, all the live objects are marked. Because unreachable objects cannot be identified singly, all the reachable objects must be identified. Therefore, everything else must be garbage. The process of marking all reachable objects is also known as tracing. The active state of the JVM is made up of the saved registers for each thread, the set of stacks that represent the threads, the static’s that are in Java classes, and the set of local and global JNI references. All functions that are invoked in the JVM itself cause a frame on the C stack. This frame might contain instances of objects as a result of either an assignment to a local variable, or a parameter that is sent from the caller. All these references are treated equally by the tracing routines. The Garbage Collector views the stack of a thread as a set of 4-byte fields (8 bytes in 64-bit architecture) and scans them from the top to the bottom of each of the stacks. The Garbage Collector assumes that the stacks are 4-byte aligned (8-byte aligned in 64-bit architecture). Each slot is examined to see whether it points at an object that is in the heap. Note that this does not make it necessarily a pointer to an object, because it might be only an accidental combination of bits in a float or integer. So, when the Garbage Collector performs the scan of a thread stack, it handles conservatively anything that it finds. Anything that points at an object is assumed to be an object, but the object in question must not be moved during garbage collection. A slot is thought to be a pointer to an object if it meets these three requirements: It is grained (aligned) on an 8-byte boundary.It is inside the bounds of the heap.The allocbit is on. Objects that are referenced in this way are known as roots, and have their dosed bit set on to indicate that they cannot be moved. The setting of dosed bits is done only if the Garbage Collector is to perform a compaction. Tracing can now proceed accurately. That is, the Garbage Collector can find references in the roots to other objects and, because it knows that they are real references, it can move them during compaction because it can change the reference. The tracing process uses a stack that can hold 4 KB entries. All references that are pushed to the stack are marked at the same time by setting the relevant markbit to on. The roots are marked and pushed to the stack and then the Garbage Collector starts to pop entries off the stack and trace them. Normal objects (not arrays) are traced by using the mtpr to access the classblock, which tells where references to other objects are to be found in this object. As each reference is found, if it is not already marked, it is marked and pushed. Array objects are traced by looking at each array entry and, if it is not already marked, it is marked and pushed. Some additional code traces a small portion of the array at a time, to try to avoid mark stack overflow. The above process continues repeatedly until the mark stack eventually becomes empty.[/quote] [sizemedium][b]实现例子Mono[/b][/size] 不熟悉Mono的同学们[urlhttp://www.mono-project.com/]Mono[/url]不是一种[urlhttp://java.sun.com/docs/books/jvms/]JVM[/url]实现而是一种[urlhttp://www.ecma-international.org/publications/standards/Ecma-335.htm]CLI[/url]实现。不过CLI与JVM有许多相似之处所以顺便拿Mono来举例 早期版本的Mono采用Boehm GC使用的是半保守模式。可以参考以下文档的描述 [urlhttp://www.mono-project.com/Mono:Runtime#Mono.27s_use_of_Boehm_GC]Mono’s use of Boehm GC[/url] [quote][sizesmall]Mono’s use of Boehm GC[/size] We are using the Boehm conservative GC in precise mode. There are a few areas that the GC scans for pointers to managed objects: The heap (where other managed objects are allocated)thread stacks and registersstatic data areadata structures allocated by the runtime (1) is currently handled in mostly precise mode: almost always the GC will only consider memory words that contain only references to the heap, so there is very little chance of pointer misidentification and hence memory retention as a result. The new GC requires a fully precise mode here, so it will improve things marginally. The details about mostly precise have to do with large objects with sparse bitmaps of references and the handling of multiple appdomains safely. (2) is always scanned conservatively. This will be true for the new GC, too, at least for the first versions, where I’ll have my own share of fun at tracking the bugs that a moving generational GC will expose. Later we’ll conservatively scan only the unmanaged part of the stacks. (3) We already optimized this both with Boehm and the current GC to work in precise mode. (4) I already optimized this to work in mostly precise mode (ie some data structures are dealt with precisely, others not yet). I’ll need to do more work in this area, especially for the new GC, where having pinned objects can be a significant source of pain.[/quote] 从Mono 2.8开始一种名为[urlhttp://www.mono-project.com/Compacting_GC]SGen[/url]的新GC实现被包含在发布包中。但这个版本的SGen仍然是半保守式GC。 未来Mono将逐渐转为使用完全准确式的GC。这篇文档描述了设计思路[urlhttp://www.mono-project.com/Compacting_GC#Precise_Stack_Marking]Precise Stack Marking[/url] [sizemedium][b]进一步阅读[/b][/size] [urlhttp://citeseer.ist.psu.edu/viewdoc/summary?doi10.1.1.47.6924]Finding References in Java Stacks[/url] 1997年Sun Labs的一篇论文。主要讲解了在Java的栈里找出引用的特点、问题与解决思路特别是与jsr带来的问题。其中前三章概括介绍了保守式GC与准确式GC的概念、准确式GC涉及的元数据stack map、生成stack map的方法等内容。 [urlhttp://labs.oracle.com/techrep/1998/abstract-70.html]GC Points in a Threaded Environment[/url] 1998年Sun Labs的一篇论文。讲解了多线程条件下允许GC发生的位置所谓的“GC point”也称为“safepoint”。 [urlhttp://book.douban.com/subject/4873919/]Oracle JRockit: The Definitive Guide[/url] 第三章84-87页Livemaps 介绍了JRockit的GC是如何找到活动记录中的引用的。JRockit的livemap也是由JIT编译器生成出来的。 [urlhttp://www.usenix.org/events/jvm01/full_papers/barabash/barabash.pdf]Mostly Accurate Stack Scanning[/url] 2001年IBM出的一篇论文。讲解了几种半保守式扫描栈的方法。 [urlhttp://www.cs.tufts.edu/~nr/cs257/archive/james-stichnoth/p118-stichnoth.pdf]Support for Garbage Collection at Every Instruction in a Java Compiler[/url] 1999年Intel出的一篇论文。它的论点是通过采用压缩技术即便为每条指令都生成GC map消耗的空间也可以接受。 虽然如此但现在主流的VM里没有一个是会为每条指令都生成GC map的相反多数是不但只在safepoint才生成GC map而且平时还将GC map压缩起来放在内存里。 [urlhttp://d3s.mff.cuni.cz/publications/cpe0X.pdf]Accurate Garbage Collection in Uncooperative Environments Revisited[/url] 2002年的一篇论文描述了[urlhttp://www.ovmj.net/index.html]Ovm[/url]是如何在缺乏编译器支持的情况下实现准确式GC。Ovm是一种比较特别的JVM实现它先把Java字节码翻译为C/C然后再用GCC之类的C/C编译器生成最终的代码。本来Java比较容易实现完全准确的GC但经过中间C/C这层事情就变得复杂了。 [urlhttp://citeseer.ist.psu.edu/viewdoc/summary?doi10.1.1.42.595]Runtime Tags Aren’t Necessary[/url] 1988年Andrew W. Appel虎书作者写的一篇论文。它提出了在[urlhttp://en.wikipedia.org/wiki/ML_(programming_language)]ML语言[/url]的静态多态类型系统的支持下GC可以怎样在不使用tag的前提下将引用与非引用区分开。 [urlhttp://llvm.org/docs/GarbageCollection.html]Accurate Garbage Collection with LLVM[/url] 编译器框架LLVM的官方文档介绍了如何将LLVM与准确式GC结合起来。后面这个演示稿介绍了VMKit是如何将MMTk与LLVM整合在一起实现准确式GC的[urlhttp://llvm.org/devmtg/2009-10/Geoffray_GarbageCollectionVMKit.pdf]Precise and Efficient Garbage Collection in VMKit with MMTk[/url]。 Ruby Hacking Guide第五章 垃圾收集is_pointer_to_heap() [urlhttp://www.loveruby.net/ja/rhg/book/gc.html]原版日文[/url] [urlhttp://www.iteye.com/wiki/Ruby_Hacking_Guide/1276-garbage-collection]ItEye专栏里的中文翻译[/url] 介绍了CRuby是如何区分一个数据是不是指向GC堆中的指针。CRuby的GC也是属于半保守式的。 [urlhttp://book.douban.com/subject/4881935/]ガベージコレクションのアルゴリズムと実装[/url] 介绍GC的算法与实现的一本书。其中11.5与12.4小节分别介绍了Rubinius与V8的准确式GC的一些设计。 [urlhttp://book.douban.com/subject/1484763/]Shared Source CLI Essentials[/url], 249-250页, Scheduling Collection [urlhttp://callvirt.net/blog/files/Shared%20Source%20CLI%202.0%20Internals.pdf]Shared Source CLI 2.0 Internals[/url], 253-254页, Scheduling Collection 介绍SSCLI的书的第一版与第二版第二版是免费的电子版点上面的链接可以下载到。 这本书在[urlhttp://rednaxelafx.iteye.com/blog/631981]之前一帖[/url]里介绍过强力推荐对VM的实现感兴趣的同学阅读。前提是能接受[urlhttp://www.microsoft.com/resources/msdn/en-us/MSDN-FILES/027/002/097/ShSourceCLILicense.htm]SSCLI License[/url]。 上面提到的章节里介绍了SSCLI的safepoint与GC map。相关代码可以参考 [urlhttp://www.koders.com/cpp/fid9E067772586484024BB99A1288EDAEF4F1DBD8DE.aspx]sscli20\sscli20\clr\src\vm\fjit_eetwain.cpp[/url] [urlhttp://www.koders.com/cpp/fidC51589DDEBF651DAF0DEC0677987631E431F51C5.aspx]sscli20\sscli20\clr\src\fjit\fjitencode.cpp[/url] 既然都提到了Mono和SSCLI那顺带也提一下微软的CLI实现CLR的玩法吧。 [urlhttp://msdn.microsoft.com/en-us/library/bb190764.aspx]MSDN: SOS.dll (SOS Debugging Extension)[/url] 这篇MSDN文档介绍了随CLR一起发布的SOS扩展的命令。其中
http://www.dnsts.com.cn/news/72605.html

相关文章:

  • 做美工要开通什么网站的会员呢赣州律师网站建设
  • 帮别人做彩票网站犯法嘛教育网站模块建设
  • 网站内容多 询盘网页设计网站哪个公司好
  • PS的网站东莞网站关键词
  • 权威的手机排行榜网站怎样手机做网站教程
  • 九号线香网站建设php 网站开发360
  • 百度网站如何建设微信公众号开发是否需要建立网站
  • 友谊路街道网站建设天眼查登录入口
  • 网站推广策划的思路包括哪些内容去哪个网站有客户找做标书的
  • 找人建设一个网站大概需要多少费用伊犁网站建设
  • 成都户外网站建设怎么建立一个网站?
  • 营销型企业网站wordpress一键生成
  • 网站内容授权书建设网站的行业现状
  • 桂林网站优化注意事项品牌视觉形象设计案例
  • 网站后台管理布局wordpress thesis 开发
  • 做现货黄金的金融网站济南最好的网站制作公司哪家好
  • 深圳品牌网站制作报价福州网站如何制作
  • 杭州电信网站备案wordpress怎么设置语言为中文
  • 菏泽网站制建设哪家好网站建设泽宇
  • 有哪些外贸网站深圳企业管理咨询公司
  • 国外好的室内设计网站分类信息网站建设计划
  • 记事本怎样做网站中信建设有限责任公司电话
  • 免费国外建站新浪网页游戏
  • 网站建设app开发小程序开发含山县建设局网站下载
  • 网站被盗用做网站宣传图的网站
  • 网站音乐播放器插件厦门网站建设团队
  • 网站设计与网页制作正文网站 简约
  • 如何自学网站制作网站建设中国十强
  • 惠州自适应网站建设安阳网红
  • 哈尔滨模板建站公司wordpress显示分类