├── .gitignore ├── README.md ├── book ├── Book-JRockit权威指南.pdf ├── Book-垃圾回收的算法与实现.pdf ├── Book-深入Java虚拟机-JVM-G1GC的算法与实现.pdf ├── Book-深入理解Java虚拟机V3-周志明.pdf ├── README.md ├── document │ ├── Oracle-HotSpot Virtual Machine Garbage Collection.pdf │ ├── Oracle-JSR-133.pdf │ ├── Oracle-Java Platform, Standard Edition Troubleshooting Guide.pdf │ ├── Oracle-Java Virtual Machine Guide.pdf │ ├── Oracle-Memory Management in the Java HotSpot Virtual Machine.pdf │ ├── Oracle-The Java Virtual Machine Specification-14.pdf │ ├── Oracle-The Java Virtual Machine Specification-8.pdf │ ├── Oracle-Troubleshooting Guide.pdf │ ├── Oracle-jls14.pdf │ ├── Plumbr Handbook Java Garbage Collection.pdf │ └── Plumbr Handbook java lang OutOfMemoryError.pdf └── slides │ ├── A-JVM-DOES-WHAT_Eva Andreasson.pdf │ ├── A-JVM-Does-What-Cliff Click.pdf │ ├── Compilation in the HotSpot VM-Zoltan-Majo.pdf │ ├── Creating a language on the JVM-Ola Bini.pdf │ ├── Dissecting the Hotspot JVM-Martin Toshev.pdf │ ├── EvolvingTheJavaPlatform-OlaBini.pdf │ ├── Inside-Java-Virtual-Machine.pdf │ ├── Introduction-to-HotSpot-Internals-Paul Nauman.pdf │ ├── Java 8-HotSpot JVM options cheatsheet.pdf │ ├── Java HotSpot Virtual Machine-2007-Peter-Kessler.pdf │ ├── Java 虚拟机面试题.pdf │ ├── The Common Language Runtime (CLR)-Mark Sapossnek.pdf │ ├── The Hotspot Java Virtual Machine-Paul Hohensee.pdf │ ├── The Java HotSpot VM Under the Hood-2018-Tobias Hartmann.pdf │ ├── Troubleshooting Memory Problems-Poonam Parhar.pdf │ └── Using-Java-Flight-Recorder-Marcus Hirt.pdf ├── examples ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── lili │ └── examples │ ├── CglibDemo.java │ ├── HeapDemo.java │ ├── OOMException.java │ ├── Test01.java │ ├── Test02.java │ ├── Test03.java │ ├── Test04.java │ ├── Test05.java │ ├── Test06.java │ ├── Test07.java │ └── oom │ ├── case1 │ ├── JavaheapspaceMemoryLeakKeyLessEntryOOM.java │ └── JavaheapspaceOOM.java │ ├── case2 │ ├── GCoverheadlimitWrapper.java │ └── MetaspaceMicroGenerator.java │ └── case3 │ ├── CreateNewNativeThreadMakeThread.java │ ├── OOM.java │ ├── OOM2.java │ └── RequestArraySizeExceedsVMlimitArrayMemory.java ├── paper ├── Design of the Java HotSpot.pdf ├── JVM versus CLRA Comparative Study.pdf ├── README.md └── The Architecture of Virtual machines.pdf ├── pom.xml ├── practicaljvm ├── README.md ├── pom.xml └── src │ └── main │ └── java │ ├── ch1 │ ├── CMethod.java │ ├── FloatNumber.java │ └── IntNumber.java │ ├── ch10 │ ├── brkparent │ │ ├── ClassLoaderTest.java │ │ ├── DemoA.java │ │ └── OrderClassLoader.java │ ├── cl │ │ └── PrintClassLoaderTree.java │ ├── clshot │ │ ├── DemoA.java │ │ ├── DoopRun.java │ │ ├── MyClassLoader.java │ │ └── SameNameClass.java │ ├── findorder │ │ ├── FindClassOrder.java │ │ ├── FindClassOrder2.java │ │ ├── FindClassOrder3.java │ │ └── HelloLoader.java │ ├── intern │ │ └── StringIntern.java │ ├── reflection │ │ └── ReflectionMain.java │ └── staticdead │ │ ├── ChildStatic.java │ │ ├── MultiEntryClinitMain.java │ │ ├── SimpleStatic.java │ │ ├── StaticA.java │ │ ├── StaticB.java │ │ ├── StaticDeadLockMain.java │ │ └── StaticFinalClass.java │ ├── ch11 │ ├── agent │ │ ├── MANIFEST.MF_addtimestat │ │ ├── PreMainAddTimeStatAgent.java │ │ ├── PreMainTraceAgent.java │ │ ├── RunAccountMain.java │ │ └── attach │ │ │ ├── AttachToolMain.java │ │ │ └── RunLoopAccountMain.java │ ├── aop │ │ ├── proxy │ │ │ ├── Account.java │ │ │ ├── AccountFactory.java │ │ │ └── AccountQuery.java │ │ ├── securitycheck │ │ │ ├── Account.java │ │ │ ├── Account_Dst.java │ │ │ ├── AddSecurityCheckClassAdapter.java │ │ │ ├── AddSecurityCheckMethodAdapter.java │ │ │ ├── RunAccountMain.java │ │ │ ├── SecurityChecker.java │ │ │ └── SecurityWeaveGenerator.java │ │ └── timestat │ │ │ ├── Account.java │ │ │ ├── RunTimeStatMainAfterGen.java │ │ │ ├── TimeStat.java │ │ │ ├── TimeStatClassAdapter.java │ │ │ ├── TimeStatMethodAdapter.java │ │ │ └── TimeStatWeaveGenerator.java │ ├── calc │ │ └── Calc.java │ ├── compile │ │ ├── CompileOptimization.java │ │ ├── FinalFlag.java │ │ └── VarString.java │ ├── inst │ │ ├── Inst.java │ │ ├── Inst2.java │ │ ├── InvokeCode.java │ │ └── SyncAdd.java │ ├── inv │ │ ├── DynBootStrap.java │ │ ├── DynInvokerSample.java │ │ ├── FieldMethodHandle.java │ │ ├── RelectionMain.java │ │ ├── Simple.java │ │ ├── SimpleCallSite.java │ │ ├── SimpleMethodHandle.java │ │ ├── SimplePrivateMethodHandle.java │ │ ├── SimpleStaticMethodHandle.java │ │ ├── SimpleSuperMethodHandle.java │ │ ├── SpeInvokerSample.java │ │ ├── dyn │ │ │ ├── DynBootStrap.java │ │ │ └── DynInvokerSample.java │ │ └── mtype │ │ │ ├── DynBootStrap.java │ │ │ └── MethodTypeInvokerSample.java │ └── jit │ │ ├── C1C2TimeMain.java │ │ ├── CodeCacheJit.java │ │ ├── IntCompMain.java │ │ ├── JITSimpleTest.java │ │ ├── JitClassLoader.java │ │ ├── Osr.java │ │ ├── deopt │ │ ├── DBWriter.java │ │ ├── WriterMain.java │ │ └── WriterService.java │ │ └── inline │ │ └── InLineMain.java │ ├── ch2 │ ├── SimpleArgs.java │ ├── heap │ │ └── SimpleHeap.java │ ├── localvar │ │ ├── LocalVar.java │ │ └── LocalVarGC.java │ ├── onstackalloc │ │ └── OnStackTest.java │ ├── perm │ │ ├── BeanGeneratorObj.java │ │ ├── CglibBean.java │ │ └── PermTest.java │ └── xss │ │ └── TestStackDeep.java │ ├── ch3 │ ├── heap │ │ ├── AccessDirectBuffer.java │ │ ├── AllocBigDirectBuffer.java │ │ ├── AllocDirectBuffer.java │ │ ├── DumpOOM.java │ │ ├── HeapAlloc.java │ │ └── newsize │ │ │ ├── NewSizeDemo.java │ │ │ └── NewSizeRatio.java │ ├── trace │ │ ├── SimpleGc.java │ │ ├── UnloadClass.java │ │ └── UnloadClassLoader.java │ └── xss │ │ └── TestStackDeep.java │ ├── ch4 │ ├── ref │ │ ├── CanReliveObj.java │ │ ├── PhantomRef.java │ │ ├── SoftRef.java │ │ ├── SoftRefQ.java │ │ ├── TraceCanReliveObj.java │ │ ├── WeakRef.java │ │ └── WeakRefQ.java │ └── stw │ │ ├── StopWorldTest.java │ │ └── StopWorldTest_MinorGC.java │ ├── ch5 │ ├── AllocEden.java │ ├── BigObject.java │ ├── ComputeTenuringThreshold.java │ ├── DisableExplictGC.java │ ├── ExplicitGCInvokesConcurrent.java │ ├── LongFinalize.java │ ├── MaxTenuringThreshold.java │ ├── PretenureSizeThreshold.java │ ├── ScavengeBeforeFullGC.java │ ├── UseTLAB.java │ ├── cms │ │ └── CMSTest.java │ ├── g1 │ │ └── G1Test.java │ └── noclassgc │ │ ├── BeanGeneratorObj.java │ │ ├── CglibBean.java │ │ └── PermTest.java │ ├── ch6 │ ├── HoldNetMain_BTrace.java │ ├── UseTlab.java │ └── hold │ │ ├── DeadLock.java │ │ ├── HProfTest.java │ │ ├── HoldCPUMain.java │ │ ├── HoldIOMain.java │ │ ├── HoldLockMain.java │ │ ├── HoldMemoryMain.java │ │ └── HoldNetMain.java │ ├── ch7 │ ├── heap │ │ ├── Student.java │ │ ├── TraceStudent.java │ │ └── WebPage.java │ ├── oom │ │ ├── DirectBufferOOM.java │ │ ├── MultiThreadOOM.java │ │ ├── PermOOM.java │ │ └── SimpleHeapOOM.java │ ├── program │ │ └── AveLoadTomcatOOM.java │ └── string │ │ ├── ConstantPool.java │ │ ├── JDK6StringOOM.java │ │ ├── StringBasic.java │ │ ├── StringIntern.java │ │ └── StringInternOOM.java │ ├── ch8 │ ├── atomic │ │ ├── Atomic.java │ │ └── AtomicLess.java │ ├── biased │ │ ├── Biased.java │ │ └── ThreadSafe.java │ ├── jmm │ │ ├── MultiThreadVolatileLong.java │ │ └── VolatileTest.java │ ├── lockcoarsenn │ │ └── LockCoarsen.java │ ├── lockeli │ │ └── LockEliminate.java │ └── threadsafe │ │ ├── ThreadSafe.java │ │ ├── ThreadUnSafe.java │ │ └── ThreadUnSafeMap.java │ └── ch9 │ ├── FullUser.java │ ├── SimpleUser.java │ └── asm │ ├── AsmCreateField.java │ └── AsmHelloWorld.java ├── understandingjvm ├── README.md ├── pom.xml └── src │ └── main │ └── java │ ├── ch1 │ └── Test1.java │ ├── ch10 │ ├── BADLY_NAMED_CODE.java │ ├── NameCheckProcessor.java │ ├── NameChecker.java │ ├── example1.java │ ├── example10.java │ ├── example2.java │ ├── example4.java │ ├── example5.java │ ├── example6.java │ ├── example8.java │ ├── example9.java │ ├── 清单10-1.txt │ ├── 清单10-10.txt │ ├── 清单10-11.txt │ ├── 清单10-12.txt │ ├── 清单10-13.txt │ ├── 清单10-2.txt │ ├── 清单10-3.txt │ ├── 清单10-4.txt │ ├── 清单10-5.txt │ ├── 清单10-6.txt │ ├── 清单10-7.txt │ ├── 清单10-8.txt │ └── 清单10-9.txt │ ├── ch11 │ └── 清单11-2.txt │ ├── ch12 │ ├── Singleton.java │ └── VolatileTest.java │ ├── ch13 │ ├── 清单13-2.txt │ ├── 清单13-3.txt │ ├── 清单13-4.txt │ └── 清单13-5.txt │ ├── ch2 │ ├── DirectMemoryOOM.java │ ├── HeapOOM.java │ ├── JavaMethodAreaOOM.java │ ├── JavaVMStackOOM.java │ ├── JavaVMStackSOF.java │ ├── RuntimeConstantPoolOOM.java │ └── RuntimeConstantPoolOOM2.java │ ├── ch3 │ ├── FinalizeEscapeGC.java │ ├── ReferenceCountingGC.java │ ├── Test35.java │ ├── Test36.java │ ├── Test37.java │ ├── Test38.java │ └── Test39.java │ ├── ch4 │ ├── BTraceTest.java │ ├── Bar.java │ ├── Test410.java │ ├── Test45.jsp │ ├── Test48.java │ ├── Test49.java │ └── TracingScript .java │ ├── ch5 │ └── EclipseStartTime_1.0.0.201011281102.jar │ ├── ch6 │ ├── GetSignature.java │ ├── OnlyMe.java │ └── TestClass.java │ ├── ch7 │ ├── ClassLoaderTest.java │ ├── FieldResolution.java │ ├── NotInitialization2.java │ ├── NotInitialization3.java │ ├── SuperClass.java │ ├── Test.java │ ├── Test76.java │ └── Test77.java │ ├── ch8 │ ├── Dispatch.java │ ├── DynamicDispatch.java │ ├── InvokeDynamicTest.java │ ├── MethodHandleTest.java │ ├── Overload.java │ ├── SonTest.java │ ├── StaticDispatch.java │ ├── StaticResolution.java │ ├── Test81.java │ ├── Test82.java │ ├── Test83.java │ └── Test84.java │ └── ch9 │ ├── 98.jsp │ ├── ByteUtils.java │ ├── ClassModifier.java │ ├── DynamicProxyTest.java │ ├── HackSystem.java │ ├── HotSwapClassLoader.java │ └── JavaClassExecuter.java ├── up.push.git.sh └── wikipedia ├── README.md └── REVIEW.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | #*.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | 26 | ### IntelliJ IDEA ### 27 | .idea 28 | *.iws 29 | *.iml 30 | *.ipr 31 | 32 | target 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JVM-PRACTICE 2 | 3 | 整理的JVM的一些资料,包括周志明《深入理解JVM》,葛一鸣《实战JVM》代码以及自己测试Demo。 4 | 5 | 以及中国所有出版的JVM的书籍整理。还有国外的PPT,论文的汇总。 6 | 7 | # 国内出版的JVM的书汇总(总共27本) 8 | 9 | ## 初学者(8本) 10 | 11 | 1. 《深入理解Java虚拟机:JVM高级特性与实践(第3版)》- 周志明 12 | 2. 《深入Java虚拟机(原书第2版)---SUN公司核心技术丛书》 - Bill Venners 13 | 3. 《实战JAVA虚拟机 JVM故障诊断与性能优化》 - 葛一鸣 14 | 4. 《深入理解JVM & G1 GC》 周明耀 15 | 5. 《Java虚拟机精讲》 高翔龙 16 | 6. 《自己动手写Java虚拟机》 - 张秀宏 使用Go实现的 17 | 7. 《自己动手写Python虚拟机》 18 | 8. 《深入浅出:Java虚拟机设计与实现》-华保健 19 | 20 | ## 进阶者(12) 21 | 22 | 1. 《揭秘Java虚拟机:JVM设计原理与实现》 封亚非 23 | 2. 《虚拟机设计与实现:以JVM为例》- 李晓峰 24 | 3. 《Java虚拟机规范-JavaSE8》- Sun团队 25 | 4. 《深入理解JVM字节码/Java核心技术系列》 张亚 26 | 5. 《解析Java虚拟机开发--权衡优化高效和安全的最优方案》 27 | 6. 《Java虚拟机基础教程》Vincent van der Leun 28 | 7. 《深入解析Java虚拟机HotSpot》 杨易 29 | 8. 《深入理解Android:Java虚拟机ART (Chinese Edition)》 30 | 9. 《JRockit权威指南:深入理解JVM》 31 | 10. 《深入Java虚拟机:JVM G1 GC的算法与实现》 日-中村成洋 32 | 11. 《垃圾回收算法与实现》 日-中村成洋 33 | 12. 《HotSpot实战》 - 陈涛 34 | 13. 《深入探索JVM垃圾回收》-彭成寒 35 | 14. 《新一代垃圾回收器-ZGC设计与实现》- 彭成寒 36 | 37 | ## 深入者(5) 38 | 39 | 1. 《虚拟机:系统与进程的通用平台》 James E. Smith and Ravi Nair Virtual machines - versatile platforms for systems and processes 40 | 2. 《JVM G1源码分析和调优》 - 彭成寒 41 | 3. 《深入剖析Java虚拟机 : 源码剖析与实例详解(基础卷)》 42 | 4. 《垃圾回收算法手册-自动内存管理的艺术》 43 | 5. 《GraalVM与Java静态编译:原理与应用林子熠》 44 | 45 | # 论文 46 | 47 | [paper](/paper) 48 | 49 | # Slides 50 | 51 | [slides](/book/slides) -------------------------------------------------------------------------------- /book/Book-JRockit权威指南.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/Book-JRockit权威指南.pdf -------------------------------------------------------------------------------- /book/Book-垃圾回收的算法与实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/Book-垃圾回收的算法与实现.pdf -------------------------------------------------------------------------------- /book/Book-深入Java虚拟机-JVM-G1GC的算法与实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/Book-深入Java虚拟机-JVM-G1GC的算法与实现.pdf -------------------------------------------------------------------------------- /book/Book-深入理解Java虚拟机V3-周志明.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/Book-深入理解Java虚拟机V3-周志明.pdf -------------------------------------------------------------------------------- /book/README.md: -------------------------------------------------------------------------------- 1 | # JVM书籍 -------------------------------------------------------------------------------- /book/document/Oracle-HotSpot Virtual Machine Garbage Collection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-HotSpot Virtual Machine Garbage Collection.pdf -------------------------------------------------------------------------------- /book/document/Oracle-JSR-133.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-JSR-133.pdf -------------------------------------------------------------------------------- /book/document/Oracle-Java Platform, Standard Edition Troubleshooting Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-Java Platform, Standard Edition Troubleshooting Guide.pdf -------------------------------------------------------------------------------- /book/document/Oracle-Java Virtual Machine Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-Java Virtual Machine Guide.pdf -------------------------------------------------------------------------------- /book/document/Oracle-Memory Management in the Java HotSpot Virtual Machine.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-Memory Management in the Java HotSpot Virtual Machine.pdf -------------------------------------------------------------------------------- /book/document/Oracle-The Java Virtual Machine Specification-14.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-The Java Virtual Machine Specification-14.pdf -------------------------------------------------------------------------------- /book/document/Oracle-The Java Virtual Machine Specification-8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-The Java Virtual Machine Specification-8.pdf -------------------------------------------------------------------------------- /book/document/Oracle-Troubleshooting Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-Troubleshooting Guide.pdf -------------------------------------------------------------------------------- /book/document/Oracle-jls14.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Oracle-jls14.pdf -------------------------------------------------------------------------------- /book/document/Plumbr Handbook Java Garbage Collection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Plumbr Handbook Java Garbage Collection.pdf -------------------------------------------------------------------------------- /book/document/Plumbr Handbook java lang OutOfMemoryError.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/document/Plumbr Handbook java lang OutOfMemoryError.pdf -------------------------------------------------------------------------------- /book/slides/A-JVM-DOES-WHAT_Eva Andreasson.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/A-JVM-DOES-WHAT_Eva Andreasson.pdf -------------------------------------------------------------------------------- /book/slides/A-JVM-Does-What-Cliff Click.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/A-JVM-Does-What-Cliff Click.pdf -------------------------------------------------------------------------------- /book/slides/Compilation in the HotSpot VM-Zoltan-Majo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Compilation in the HotSpot VM-Zoltan-Majo.pdf -------------------------------------------------------------------------------- /book/slides/Creating a language on the JVM-Ola Bini.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Creating a language on the JVM-Ola Bini.pdf -------------------------------------------------------------------------------- /book/slides/Dissecting the Hotspot JVM-Martin Toshev.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Dissecting the Hotspot JVM-Martin Toshev.pdf -------------------------------------------------------------------------------- /book/slides/EvolvingTheJavaPlatform-OlaBini.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/EvolvingTheJavaPlatform-OlaBini.pdf -------------------------------------------------------------------------------- /book/slides/Inside-Java-Virtual-Machine.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Inside-Java-Virtual-Machine.pdf -------------------------------------------------------------------------------- /book/slides/Introduction-to-HotSpot-Internals-Paul Nauman.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Introduction-to-HotSpot-Internals-Paul Nauman.pdf -------------------------------------------------------------------------------- /book/slides/Java 8-HotSpot JVM options cheatsheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Java 8-HotSpot JVM options cheatsheet.pdf -------------------------------------------------------------------------------- /book/slides/Java HotSpot Virtual Machine-2007-Peter-Kessler.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Java HotSpot Virtual Machine-2007-Peter-Kessler.pdf -------------------------------------------------------------------------------- /book/slides/Java 虚拟机面试题.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Java 虚拟机面试题.pdf -------------------------------------------------------------------------------- /book/slides/The Common Language Runtime (CLR)-Mark Sapossnek.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/The Common Language Runtime (CLR)-Mark Sapossnek.pdf -------------------------------------------------------------------------------- /book/slides/The Hotspot Java Virtual Machine-Paul Hohensee.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/The Hotspot Java Virtual Machine-Paul Hohensee.pdf -------------------------------------------------------------------------------- /book/slides/The Java HotSpot VM Under the Hood-2018-Tobias Hartmann.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/The Java HotSpot VM Under the Hood-2018-Tobias Hartmann.pdf -------------------------------------------------------------------------------- /book/slides/Troubleshooting Memory Problems-Poonam Parhar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Troubleshooting Memory Problems-Poonam Parhar.pdf -------------------------------------------------------------------------------- /book/slides/Using-Java-Flight-Recorder-Marcus Hirt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/book/slides/Using-Java-Flight-Recorder-Marcus Hirt.pdf -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # 自己测试的例子 -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jvm-practice 7 | org.lili 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | examples 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/CglibDemo.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | /** 4 | * Created by lili on 2017/5/17. 5 | */ 6 | public class CglibDemo { 7 | public static void main(String[] args) { 8 | for (int i = 0; i < 1000000; i++) { 9 | 10 | 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/HeapDemo.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | /** 4 | * Created by lili on 2017/5/17. 5 | */ 6 | public class HeapDemo { 7 | 8 | private static final int size = 1 * 1024 * 1024; 9 | 10 | /** 11 | * vm config: 12 | * -Xmx20m -Xms20m -Xmn1m -XX:+PrintGCDetails -XX:+UseSerialGC 13 | * 14 | * -Xmx20m -Xms20m -Xmn15m -XX:+PrintGCDetails -XX:+UseSerialGC 15 | * 16 | * -Xmx20m -Xms20m -Xmn7m -XX:+PrintGCDetails -XX:+UseSerialGC 17 | * 18 | * -Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC 19 | * 20 | * -Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:NewRatio=1 -XX:+PrintGCDetails -XX:+UseSerialGC 21 | * 22 | * 23 | * 24 | */ 25 | 26 | 27 | public static void main(String[] args) { 28 | 29 | 30 | byte[] b = null; 31 | for (int i = 0; i < 10; i++) { 32 | b = new byte[size]; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/OOMException.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | import java.util.Vector; 4 | 5 | /** 6 | * Created by lili on 2017/5/17. 7 | */ 8 | public class OOMException { 9 | public static void main(String[] args) { 10 | Vector v = new Vector(); 11 | for (int i = 0; i < 25; i++) { 12 | v.add(new byte[1024*1024]); //1M 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test01.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | 4 | public class Test01 { 5 | 6 | public static void main(String[] args) { 7 | 8 | // System.out.println(args[0]); 9 | // System.out.println(args[1]); 10 | 11 | //-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags 12 | 13 | //查看GC信息 14 | System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); 15 | System.out.println("free memory:" + Runtime.getRuntime().freeMemory()); 16 | System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); 17 | 18 | byte[] b1 = new byte[1*1024*1024]; 19 | System.out.println("分配了1M"); 20 | System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); 21 | System.out.println("free memory:" + Runtime.getRuntime().freeMemory()); 22 | System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); 23 | 24 | byte[] b2 = new byte[4*1024*1024]; 25 | System.out.println("分配了4M"); 26 | System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); 27 | System.out.println("free memory:" + Runtime.getRuntime().freeMemory()); 28 | System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); 29 | 30 | int a = 0x00000000fec00000; 31 | int b = 0x00000000fee10000; 32 | System.out.println((b-a)/1024); 33 | for (;;){} 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test02.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | public class Test02 { 4 | 5 | public static void main(String[] args) { 6 | 7 | //第一次配置 8 | //-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC 9 | 10 | //第二次配置 11 | //-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC 12 | 13 | //第三次配置 14 | //-XX:NewRatio=老年代/新生代 一般 3 15 | //-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC 16 | 17 | byte[] b = null; 18 | //连续向系统申请10MB空间 19 | for(int i = 0 ; i <10; i ++){ 20 | b = new byte[1*1024*1024]; 21 | } 22 | 23 | for (;;){} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test03.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | import java.util.Vector; 4 | 5 | public class Test03 { 6 | 7 | public static void main(String[] args) { 8 | 9 | //-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump 10 | //堆内存溢出 11 | Vector v = new Vector(); 12 | for(int i=0; i < 5; i ++){ 13 | v.add(new Byte[1*1024*1024]); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test04.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | public class Test04 { 4 | 5 | //-Xss1m 6 | //-Xss5m 7 | 8 | //栈调用深度 9 | private static int count; 10 | 11 | public static void recursion(){ 12 | count++; 13 | recursion(); 14 | } 15 | public static void main(String[] args){ 16 | try { 17 | recursion(); 18 | } catch (Throwable t) { 19 | System.out.println("调用最大深入:" + count); 20 | t.printStackTrace(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test05.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | public class Test05 { 4 | 5 | public static void main(String[] args) { 6 | //初始的对象在eden区 7 | //参数:-Xmx64M -Xms64M -XX:+PrintGCDetails 8 | // for(int i=0; i< 5; i++){ 9 | // byte[] b = new byte[1024*1024]; 10 | // } 11 | // 12 | 13 | 14 | //测试进入老年代的对象 15 | // 16 | //参数:-Xmx1024M -Xms1024M -XX:+UseSerialGC -XX:MaxTenuringThreshold=15 -XX:+PrintGCDetails 17 | //-XX:+PrintHeapAtGC 18 | // Map m = new HashMap(); 19 | // for(int i =0; i <5 ; i++) { 20 | // byte[] b = new byte[1024*1024]; 21 | // m.put(i, b); 22 | // } 23 | // 24 | for(int k = 0; k<20; k++) { 25 | for(int j = 0; j<300; j++){ 26 | byte[] b = new byte[1024*1024]; 27 | } 28 | } 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test06.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Test06 { 7 | 8 | public static void main(String[] args) { 9 | 10 | //这种现象原因为:虚拟机对于体积不大的对象 会优先把数据分配到TLAB区域中,因此就失去了在老年代分配的机会 11 | //参数:-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB 12 | Map m = new HashMap(); 13 | for(int i=0; i< 5*1024; i++){ 14 | byte[] b = new byte[1024]; 15 | m.put(i, b); 16 | } 17 | 18 | 19 | //参数:-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 20 | /*Map m = new HashMap(); 21 | for(int i=0; i< 5; i++){ 22 | byte[] b = new byte[1024*1024]; 23 | m.put(i, b); 24 | }*/ 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/Test07.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples; 2 | 3 | 4 | public class Test07 { 5 | 6 | public static void alloc(){ 7 | byte[] b = new byte[2]; 8 | } 9 | public static void main(String[] args) { 10 | 11 | //TLAB分配 12 | //参数:-XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=102400 -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=100 -XX:-DoEscapeAnalysis -server 13 | for(int i=0; i<10000000;i++){ 14 | alloc(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case1/JavaheapspaceMemoryLeakKeyLessEntryOOM.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case1; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author lili 8 | * @date 2020/8/16 14:15 9 | * @notes 10 | */ 11 | public class JavaheapspaceMemoryLeakKeyLessEntryOOM { 12 | public static class Key { 13 | Integer id; 14 | 15 | public Key(Integer id) { 16 | this.id = id; 17 | } 18 | 19 | @Override 20 | public int hashCode() { 21 | return id.hashCode(); 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws InterruptedException { 26 | Map m = new HashMap(); 27 | 28 | Key key = new Key(1); 29 | m.put(key,"key1"); 30 | Key key2 = new Key(1); 31 | m.put(key2,"key1"); 32 | System.out.println(m.size()); 33 | 34 | 35 | //java.lang.OutOfMemoryError: GC overhead limit exceeded 36 | while (true) { 37 | for (int i = 0; i < 1000000000; i++) { 38 | if (!m.containsKey(new Key(i))) { 39 | m.put(new Key(i), "Number:" + i); 40 | } 41 | } 42 | System.out.println(m.keySet().size()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case1/JavaheapspaceOOM.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case1; 2 | 3 | /** 4 | * @author lili 5 | * @date 2020/8/16 14:07 6 | * @notes 7 | */ 8 | public class JavaheapspaceOOM { 9 | static final int MB = 1024 * 1024; 10 | static final int MBS = 1024 * 512; 11 | //java.lang.OutOfMemoryError: Java heap space 12 | //-Xmx12m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintHeapAtGC 13 | // 14 | public static void main(String[] args) throws InterruptedException { 15 | //NewRatio 2 SurvivorRatio 8 16 | //分配12M堆空间,新生代 4M,Eden 3.2M from 0.4M to 0.4M 老年代 8M 17 | int[] i = new int[2 * MB]; //2M整数,1个整数4字节,4B,总共8M 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case2/GCoverheadlimitWrapper.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case2; 2 | 3 | import java.util.Map; 4 | import java.util.Random; 5 | 6 | /** 7 | * @author lili 8 | * @date 2020/8/16 14:48 9 | * @notes 10 | */ 11 | public class GCoverheadlimitWrapper { 12 | //-Xmx20m -XX:+UseParallelGC -XX:+PrintGCDetails 13 | public static void main(String[] args) { 14 | Map map = System.getProperties(); 15 | Random r = new Random(); 16 | while (true) { 17 | map.put(r.nextInt(), "value"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case2/MetaspaceMicroGenerator.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case2; 2 | 3 | import javassist.CannotCompileException; 4 | import javassist.ClassPool; 5 | 6 | /** 7 | * @author lili 8 | * @date 2020/8/16 15:11 9 | * @notes 10 | */ 11 | public class MetaspaceMicroGenerator { 12 | 13 | public static class FullPermSpace extends Thread { 14 | @Override 15 | public void run() { 16 | for (int i = 0; i < 100_000_000; i++) { 17 | ClassPool pool = ClassPool.getDefault(); 18 | try { 19 | pool.makeClass("org.lili.examples.oom.case1.KeyLessEntry" + i).toClass(); 20 | } catch (CannotCompileException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | } 25 | } 26 | 27 | public static class FullPermSpace2 extends Thread { 28 | @Override 29 | public void run() { 30 | for (int i = 0; i < 100_000_000; i++) { 31 | ClassPool pool = ClassPool.getDefault(); 32 | try { 33 | pool.makeClass("org.lili.examples.oom.case1.LiLi" + i).toClass(); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | } 40 | 41 | //-XX:MaxPermSize=1M 不生效 -XX:MaxMetaspaceSize=64m 42 | public static void main(String[] args) throws Exception { 43 | //-XX:MaxMetaspaceSize=64m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags 44 | FullPermSpace2 fullPermSpace2 = new FullPermSpace2(); 45 | FullPermSpace fullPermSpace = new FullPermSpace(); 46 | fullPermSpace.start(); 47 | fullPermSpace2.start(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case3/CreateNewNativeThreadMakeThread.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case3; 2 | 3 | /** 4 | * @author lili 5 | * @date 2020/8/16 16:35 6 | * @notes 7 | */ 8 | public class CreateNewNativeThreadMakeThread { 9 | 10 | //Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread 11 | public static void main(String[] args) { 12 | while (true) { 13 | new Thread(new Runnable() { 14 | @Override 15 | public void run() { 16 | try { 17 | Thread.sleep(1000000000); 18 | } catch (Exception e) { 19 | e.printStackTrace(); 20 | } 21 | } 22 | }).start(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case3/OOM.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case3; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @author lili 7 | * @date 2020/8/16 16:57 8 | * @notes 9 | */ 10 | public class OOM { 11 | public static void main(String[] args) { 12 | // java.lang.OutOfMemoryError: Java heap space 13 | ArrayList objects = new ArrayList<>(); 14 | for (int i = 0; i < 10000000; i++) { 15 | objects.add(new int[100_000_000]); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case3/OOM2.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case3; 2 | 3 | import java.text.DecimalFormat; 4 | 5 | /** 6 | * @author lili 7 | * @date 2020/8/17 16:43 8 | * @notes 9 | */ 10 | public class OOM2 { 11 | public static void main(String[] args) { 12 | while(true) { 13 | new DecimalFormat("0.000"); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/src/main/java/org/lili/examples/oom/case3/RequestArraySizeExceedsVMlimitArrayMemory.java: -------------------------------------------------------------------------------- 1 | package org.lili.examples.oom.case3; 2 | 3 | /** 4 | * @author lili 5 | * @date 2020/8/16 16:50 6 | * @notes 7 | */ 8 | public class RequestArraySizeExceedsVMlimitArrayMemory { 9 | public static void main(String[] args) { 10 | //Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 11 | for (int i = 0; i < 4; i++) { 12 | int[] arr = new int[Integer.MAX_VALUE - 1]; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /paper/Design of the Java HotSpot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/paper/Design of the Java HotSpot.pdf -------------------------------------------------------------------------------- /paper/JVM versus CLRA Comparative Study.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/paper/JVM versus CLRA Comparative Study.pdf -------------------------------------------------------------------------------- /paper/README.md: -------------------------------------------------------------------------------- 1 | # Paper 2 | 3 | Paper: https://www.cnblogs.com/WCFGROUP/p/6373416.html 4 | -------------------------------------------------------------------------------- /paper/The Architecture of Virtual machines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/paper/The Architecture of Virtual machines.pdf -------------------------------------------------------------------------------- /practicaljvm/README.md: -------------------------------------------------------------------------------- 1 | # 葛一鸣《实战Java虚拟机》源码 -------------------------------------------------------------------------------- /practicaljvm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jvm-practice 7 | org.lili 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | practicaljvm 14 | 15 | 16 | 17 | org.ow2.asm 18 | asm-all 19 | 20 | 21 | 22 | cglib 23 | cglib 24 | 25 | 26 | 27 | cglib 28 | cglib-nodep 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch1/CMethod.java: -------------------------------------------------------------------------------- 1 | package ch1; 2 | 3 | public class CMethod { 4 | // public static void new (){ 5 | // } 6 | 7 | public static void 打印(){ 8 | System.out.println("中文方法"); 9 | } 10 | 11 | public static void main(String[] args) { 12 | 打印(); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch1/FloatNumber.java: -------------------------------------------------------------------------------- 1 | package ch1; 2 | 3 | public class FloatNumber { 4 | public static void main(String[] args) { 5 | float a=-0; 6 | System.out.println(a); 7 | System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(a))); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch1/IntNumber.java: -------------------------------------------------------------------------------- 1 | package ch1; 2 | 3 | public class IntNumber { 4 | public static void main(String[] args) { 5 | int a=-10; 6 | for(int i=0;i<32;i++){ 7 | int t=(a & 0x80000000>>>i)>>>(31-i); 8 | System.out.print(t); 9 | } 10 | System.out.println(); 11 | System.out.println(Integer.toBinaryString(a)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/brkparent/ClassLoaderTest.java: -------------------------------------------------------------------------------- 1 | package ch10.brkparent; 2 | 3 | /** 4 | * 即使app classloader可以加载,这里也不会加载,因为OrderClassLoader破坏了双亲模式 5 | * @author Administrator 6 | * 7 | */ 8 | public class ClassLoaderTest { 9 | public static void main(String[] args) throws ClassNotFoundException { 10 | OrderClassLoader myLoader=new OrderClassLoader("D:/tmp/clz/"); 11 | Class clz=myLoader.loadClass("geym.zbase.ch10.brkparent.DemoA"); 12 | System.out.println(clz.getClassLoader()); 13 | 14 | System.out.println("==== Class Loader Tree ===="); 15 | ClassLoader cl=clz.getClassLoader(); 16 | while(cl!=null){ 17 | System.out.println(cl); 18 | cl=cl.getParent(); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/brkparent/DemoA.java: -------------------------------------------------------------------------------- 1 | package ch10.brkparent; 2 | 3 | public class DemoA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/cl/PrintClassLoaderTree.java: -------------------------------------------------------------------------------- 1 | package ch10.cl; 2 | 3 | public class PrintClassLoaderTree { 4 | public static void main(String[] args) { 5 | ClassLoader cl=PrintClassLoaderTree.class.getClassLoader(); 6 | while(cl!=null){ 7 | System.out.println(cl); 8 | cl=cl.getParent(); 9 | } 10 | System.out.println("String classloader:"+String.class.getClassLoader()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/clshot/DemoA.java: -------------------------------------------------------------------------------- 1 | package ch10.clshot; 2 | 3 | public class DemoA { 4 | public void hot(){ 5 | System.out.println("NewDemoA"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/clshot/DoopRun.java: -------------------------------------------------------------------------------- 1 | package ch10.clshot; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public class DoopRun { 6 | public static void main(String args[]) { 7 | while(true){ 8 | try{ 9 | MyClassLoader loader = new MyClassLoader("D:/tmp/clz"); 10 | Class cls = loader.loadClass("geym.zbase.ch10.clshot.DemoA"); 11 | Object demo = cls.newInstance(); 12 | 13 | Method m = demo.getClass().getMethod("hot", new Class[] {}); 14 | m.invoke(demo, new Object[] {}); 15 | Thread.sleep(10000); 16 | }catch(Exception e){ 17 | System.out.println("not find"); 18 | try { 19 | Thread.sleep(10000); 20 | } catch (InterruptedException e1) { 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/findorder/FindClassOrder.java: -------------------------------------------------------------------------------- 1 | package ch10.findorder; 2 | 3 | /** 4 | * -Xbootclasspath/a:D:/tmp/clz 5 | * -XBootClasspath 指定 说明加载先从启动classloader开始 6 | * @author Administrator 7 | * 8 | */ 9 | public class FindClassOrder { 10 | public static void main(String args[]){ 11 | HelloLoader loader=new HelloLoader(); 12 | loader.print(); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/findorder/HelloLoader.java: -------------------------------------------------------------------------------- 1 | package ch10.findorder; 2 | 3 | public class HelloLoader { 4 | public void print(){ 5 | System.out.println("I am in apploader"); 6 | // System.out.println("I am in Boot ClassLoader"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/intern/StringIntern.java: -------------------------------------------------------------------------------- 1 | package ch10.intern; 2 | 3 | public class StringIntern { 4 | 5 | public static void main(String[] args) { 6 | String a=Integer.toString(1)+Integer.toString(2)+Integer.toString(3); 7 | String b="123"; 8 | System.out.println(a.equals(b)); 9 | System.out.println(a==b); 10 | System.out.println(a.intern()==b); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/reflection/ReflectionMain.java: -------------------------------------------------------------------------------- 1 | package ch10.reflection; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Modifier; 5 | 6 | public class ReflectionMain { 7 | public static void main(String[] args) throws Exception { 8 | Class clzStr=Class.forName("java.lang.String"); 9 | Method[] ms=clzStr.getDeclaredMethods(); 10 | for(Method m:ms){ 11 | String mod=Modifier.toString(m.getModifiers()); 12 | System.out.print(mod+" "+ m.getName()+" ("); 13 | Class[] ps=m.getParameterTypes(); 14 | if(ps.length==0)System.out.print(')'); 15 | for(int i=0;i 5 | * 其他等待的线程,在第一个线程完成后,并不会进入 6 | * @author Administrator 7 | * 8 | */ 9 | public class MultiEntryClinitMain extends Thread{ 10 | private char flag; 11 | public MultiEntryClinitMain(char flag){ 12 | this.flag=flag; 13 | this.setName("Thread"+flag); 14 | } 15 | @Override 16 | public void run(){ 17 | try { 18 | Class.forName("geym.zbase.ch10.staticdead.Static"+flag); 19 | } catch (ClassNotFoundException e) { 20 | e.printStackTrace(); 21 | } 22 | System.out.println(getName()+" over"); 23 | } 24 | public static void main(String[] args) throws InterruptedException { 25 | MultiEntryClinitMain loadA=new MultiEntryClinitMain('A'); 26 | loadA.start(); 27 | MultiEntryClinitMain loadB=new MultiEntryClinitMain('A'); 28 | loadB.start(); 29 | 30 | } 31 | 32 | } 33 | 34 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/staticdead/SimpleStatic.java: -------------------------------------------------------------------------------- 1 | package ch10.staticdead; 2 | 3 | public class SimpleStatic { 4 | public static int id=1; 5 | public static int number; 6 | static{ 7 | number=4; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/staticdead/StaticA.java: -------------------------------------------------------------------------------- 1 | package ch10.staticdead; 2 | 3 | public class StaticA { 4 | static{ 5 | try { 6 | Thread.sleep(1000); 7 | } catch (InterruptedException e) { 8 | } 9 | try { 10 | Class.forName("geym.zbase.ch10.staticdead.StaticB"); 11 | } catch (ClassNotFoundException e) { 12 | e.printStackTrace(); 13 | } 14 | System.out.println("StaticA init OK"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/staticdead/StaticB.java: -------------------------------------------------------------------------------- 1 | package ch10.staticdead; 2 | 3 | public class StaticB { 4 | static{ 5 | try { 6 | Thread.sleep(1000); 7 | } catch (InterruptedException e) { 8 | } 9 | try { 10 | Class.forName("geym.zbase.ch10.staticdead.StaticA"); 11 | } catch (ClassNotFoundException e) { 12 | } 13 | System.out.println("StaticB init OK"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/staticdead/StaticDeadLockMain.java: -------------------------------------------------------------------------------- 1 | package ch10.staticdead; 2 | 3 | public class StaticDeadLockMain extends Thread{ 4 | private char flag; 5 | public StaticDeadLockMain(char flag){ 6 | this.flag=flag; 7 | this.setName("Thread"+flag); 8 | } 9 | @Override 10 | public void run(){ 11 | try { 12 | Class.forName("geym.zbase.ch10.staticdead.Static"+flag); 13 | } catch (ClassNotFoundException e) { 14 | e.printStackTrace(); 15 | } 16 | System.out.println(getName()+" over"); 17 | } 18 | public static void main(String[] args) throws InterruptedException { 19 | StaticDeadLockMain loadA=new StaticDeadLockMain('A'); 20 | loadA.start(); 21 | StaticDeadLockMain loadB=new StaticDeadLockMain('B'); 22 | loadB.start(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch10/staticdead/StaticFinalClass.java: -------------------------------------------------------------------------------- 1 | package ch10.staticdead; 2 | 3 | public class StaticFinalClass { 4 | public static final int i=1; 5 | public static final int j=2; 6 | } 7 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/agent/MANIFEST.MF_addtimestat: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Agent-Class: geym.zbase.ch11.agent.PreMainAddTimeStatAgent 3 | Premain-Class: geym.zbase.ch11.agent.PreMainAddTimeStatAgent 4 | Can-Redine-Classes: true 5 | Can-Retransform-Classes: true -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/agent/PreMainTraceAgent.java: -------------------------------------------------------------------------------- 1 | package ch11.agent; 2 | 3 | import java.lang.instrument.ClassFileTransformer; 4 | import java.lang.instrument.IllegalClassFormatException; 5 | import java.lang.instrument.Instrumentation; 6 | import java.lang.instrument.UnmodifiableClassException; 7 | import java.security.ProtectionDomain; 8 | 9 | /** 10 | * 11 | Manifest-Version: 1.0 12 | Agent-Class: geym.zbase.ch11.agent.PreMainTraceAgent 13 | Premain-Class: geym.zbase.ch11.agent.PreMainTraceAgent 14 | * @author geym 15 | * 16 | */ 17 | public class PreMainTraceAgent { 18 | public static void premain(String agentArgs, Instrumentation inst) 19 | throws ClassNotFoundException, UnmodifiableClassException { 20 | System.out.println("agentArgs:"+agentArgs); 21 | inst.addTransformer(new ClassFileTransformer(){ 22 | @Override 23 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 24 | ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { 25 | System.out.println("load Class:"+className); 26 | return classfileBuffer; 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/agent/RunAccountMain.java: -------------------------------------------------------------------------------- 1 | package ch11.agent; 2 | 3 | 4 | import ch11.aop.timestat.Account; 5 | 6 | /** 7 | * -javaagent d:/ja.jar 8 | * 9 | * -javaagent:d:/jat.jar=argument 10 | * @author Administrator 11 | * 12 | */ 13 | public class RunAccountMain { 14 | public static void main(String[] args) { 15 | Account account = new Account(); 16 | account.operation(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/agent/attach/AttachToolMain.java: -------------------------------------------------------------------------------- 1 | package ch11.agent.attach; 2 | 3 | import com.sun.tools.attach.*; 4 | 5 | import java.io.IOException; 6 | import java.util.List; 7 | 8 | /** 9 | * Add tools.jar 10 | * @author geym 11 | * 12 | */ 13 | public class AttachToolMain { 14 | public static void main(String[] args) throws AttachNotSupportedException, IOException, AgentLoadException, AgentInitializationException { 15 | List list = VirtualMachine.list(); 16 | for (VirtualMachineDescriptor vmd : list) 17 | { 18 | if(vmd.displayName().endsWith("RunLoopAccountMain")){ 19 | VirtualMachine virtualmachine = VirtualMachine.attach(vmd.id()); 20 | virtualmachine.loadAgent("D:\\ja.jar", "argument for agent"); 21 | System.out.println("ok"); 22 | virtualmachine.detach(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/agent/attach/RunLoopAccountMain.java: -------------------------------------------------------------------------------- 1 | package ch11.agent.attach; 2 | 3 | 4 | import ch11.aop.timestat.Account; 5 | 6 | public class RunLoopAccountMain { 7 | public static void main(String[] args) { 8 | Account account = new Account(); 9 | while(true){ 10 | account.operation(); 11 | try { 12 | Thread.sleep(1000); 13 | } catch (InterruptedException e) { 14 | e.printStackTrace(); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/proxy/Account.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.proxy; 2 | 3 | public class Account { 4 | public String query() { 5 | try { 6 | Thread.sleep(1000); 7 | } catch (InterruptedException e) { 8 | } 9 | return "result"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/proxy/AccountQuery.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.proxy; 2 | 3 | public class AccountQuery { 4 | 5 | public static void main(String[] args) { 6 | Account acc=AccountFactory.newAccount2(); 7 | long b=System.currentTimeMillis(); 8 | System.out.println(acc.query()); 9 | System.out.println(acc.query()); 10 | long e=System.currentTimeMillis(); 11 | System.out.println(e-b); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/Account.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | public class Account { 4 | public void operation() { 5 | System.out.println("operation..."); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/Account_Dst.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | public class Account_Dst { 4 | public void operation() { 5 | if(!SecurityChecker.checkSecurity()) 6 | return; 7 | System.out.println("operation......"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/AddSecurityCheckClassAdapter.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | import org.objectweb.asm.ClassVisitor; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | class AddSecurityCheckClassAdapter extends ClassVisitor { 8 | public AddSecurityCheckClassAdapter( ClassVisitor cv) { 9 | super(Opcodes.ASM5, cv); 10 | } 11 | 12 | // 重写 visitMethod,访问到 "operation" 方法时, 13 | // 给出自定义 MethodVisitor,实际改写方法内容 14 | public MethodVisitor visitMethod(final int access, final String name, 15 | final String desc, final String signature, final String[] exceptions) { 16 | MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions); 17 | MethodVisitor wrappedMv = mv; 18 | if (mv != null) { 19 | // 对于 "operation" 方法 20 | if (name.equals("operation")) { 21 | // 使用自定义 MethodVisitor,实际改写方法内容 22 | wrappedMv = new AddSecurityCheckMethodAdapter(mv); 23 | } 24 | } 25 | return wrappedMv; 26 | } 27 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/AddSecurityCheckMethodAdapter.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | import org.objectweb.asm.Label; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | class AddSecurityCheckMethodAdapter extends MethodVisitor { 8 | public AddSecurityCheckMethodAdapter(MethodVisitor mv) { 9 | super(Opcodes.ASM5,mv); 10 | } 11 | 12 | public void visitCode() { 13 | Label continueLabel = new Label(); 14 | visitMethodInsn(Opcodes.INVOKESTATIC, "geym/zbase/ch11/aop/securitycheck/SecurityChecker", 15 | "checkSecurity", "()Z"); 16 | visitJumpInsn(Opcodes.IFNE,continueLabel); 17 | visitInsn(Opcodes.RETURN); 18 | visitLabel(continueLabel); 19 | super.visitCode(); 20 | } 21 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/RunAccountMain.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | public class RunAccountMain { 4 | public static void main(String[] args) { 5 | Account account = new Account(); 6 | account.operation(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/SecurityChecker.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | public class SecurityChecker { 4 | public static boolean checkSecurity() { 5 | System.out.println("SecurityChecker.checkSecurity ..."); 6 | if((System.currentTimeMillis()&0x1)==0) 7 | return false; 8 | else 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/securitycheck/SecurityWeaveGenerator.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.securitycheck; 2 | 3 | import org.objectweb.asm.ClassReader; 4 | import org.objectweb.asm.ClassWriter; 5 | 6 | import java.io.File; 7 | import java.io.FileOutputStream; 8 | 9 | public class SecurityWeaveGenerator{ 10 | public static void main(String args[]) throws Exception { 11 | String className=Account.class.getName(); 12 | ClassReader cr = new ClassReader(className); 13 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES); 14 | AddSecurityCheckClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw); 15 | cr.accept(classAdapter, ClassReader.SKIP_DEBUG); 16 | byte[] data = cw.toByteArray(); 17 | File file = new File("bin/"+className.replaceAll("\\.", "/")+".class"); 18 | FileOutputStream fout = new FileOutputStream(file); 19 | fout.write(data); 20 | fout.close(); 21 | } 22 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/Account.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.timestat; 2 | 3 | public class Account { 4 | public void operation() { 5 | System.out.println("operation...."); 6 | try { 7 | Thread.sleep(10); 8 | } catch (InterruptedException e) { 9 | e.printStackTrace(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/RunTimeStatMainAfterGen.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.timestat; 2 | 3 | public class RunTimeStatMainAfterGen { 4 | public static void main(String[] args) { 5 | Account account = new Account(); 6 | account.operation(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/TimeStat.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.timestat; 2 | 3 | public class TimeStat { 4 | static ThreadLocal t=new ThreadLocal(); 5 | public static void start() { 6 | t.set(System.currentTimeMillis()); 7 | } 8 | 9 | public static void end(){ 10 | long time=System.currentTimeMillis()-t.get(); 11 | System.out.print(Thread.currentThread().getStackTrace()[2]+" spend:"); 12 | System.out.println(time); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/TimeStatClassAdapter.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.timestat; 2 | 3 | import org.objectweb.asm.ClassVisitor; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | public class TimeStatClassAdapter extends ClassVisitor { 8 | 9 | public TimeStatClassAdapter( ClassVisitor cv) { 10 | super(Opcodes.ASM5, cv); 11 | } 12 | // 重写 visitMethod,访问到 "operation" 方法时, 13 | // 给出自定义 MethodVisitor,实际改写方法内容 14 | public MethodVisitor visitMethod(final int access, final String name, 15 | final String desc, final String signature, final String[] exceptions) { 16 | MethodVisitor mv = cv.visitMethod(access, name, desc, signature,exceptions); 17 | MethodVisitor wrappedMv = mv; 18 | if (mv != null) { 19 | // 对于 "operation" 方法 20 | if (name.equals("operation")) { 21 | // 使用自定义 MethodVisitor,实际改写方法内容 22 | wrappedMv = new TimeStatMethodAdapter(mv); 23 | } 24 | } 25 | return wrappedMv; 26 | } 27 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/TimeStatMethodAdapter.java: -------------------------------------------------------------------------------- 1 | 2 | package ch11.aop.timestat; 3 | 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | class TimeStatMethodAdapter extends MethodVisitor implements Opcodes { 8 | public TimeStatMethodAdapter(MethodVisitor mv) { 9 | super(Opcodes.ASM5, mv); 10 | } 11 | 12 | public void visitCode() { 13 | visitMethodInsn(Opcodes.INVOKESTATIC, "geym/zbase/ch11/aop/timestat/TimeStat", "start", "()V"); 14 | super.visitCode(); 15 | } 16 | 17 | @Override 18 | public void visitInsn(int opcode) { 19 | if ((opcode >= IRETURN && opcode <= RETURN)) { 20 | // mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 21 | // mv.visitLdcInsn("after"); 22 | // mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 23 | visitMethodInsn(Opcodes.INVOKESTATIC, "geym/zbase/ch11/aop/timestat/TimeStat", "end", "()V"); 24 | } 25 | mv.visitInsn(opcode); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/aop/timestat/TimeStatWeaveGenerator.java: -------------------------------------------------------------------------------- 1 | package ch11.aop.timestat; 2 | 3 | 4 | import org.objectweb.asm.ClassReader; 5 | import org.objectweb.asm.ClassWriter; 6 | 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | 10 | public class TimeStatWeaveGenerator{ 11 | public static void main(String args[]) throws Exception { 12 | String className=Account.class.getName(); 13 | ClassReader cr = new ClassReader(className); 14 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES); 15 | TimeStatClassAdapter classAdapter = new TimeStatClassAdapter(cw); 16 | cr.accept(classAdapter, ClassReader.SKIP_DEBUG); 17 | byte[] data = cw.toByteArray(); 18 | File file = new File("bin/"+className.replaceAll("\\.", "/")+".class"); 19 | FileOutputStream fout = new FileOutputStream(file); 20 | fout.write(data); 21 | fout.close(); 22 | } 23 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/calc/Calc.java: -------------------------------------------------------------------------------- 1 | package ch11.calc; 2 | 3 | public class Calc { 4 | public int calc() { 5 | int a = 500; 6 | int b = 200; 7 | int c = 50; 8 | return (a + b) / c; 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/compile/CompileOptimization.java: -------------------------------------------------------------------------------- 1 | package ch11.compile; 2 | 3 | public class CompileOptimization { 4 | public int time=3600*1000; 5 | 6 | public void cirlcle(){ 7 | for(int i=0;i<60*60*24*1000;i++){ 8 | 9 | } 10 | } 11 | 12 | public static void createString(){ 13 | String info1="select * from test"; 14 | String info2="select * "+"from test"; 15 | String info3="select * ".concat("from test"); 16 | System.out.println(info1==info2); 17 | System.out.println(info1==info3); 18 | System.out.println(info2==info3); 19 | System.out.println(info2==info3.intern()); 20 | } 21 | 22 | public void swtich(int i){ 23 | switch(i){ 24 | case 1:break; 25 | case 2:break; 26 | case 5:break; 27 | default: 28 | System.out.println(""); 29 | } 30 | } 31 | 32 | public void checkflag(){ 33 | if(FinalFlag.flag){ 34 | System.out.println("flag is true"); 35 | }else{ 36 | System.out.println("flag is false"); 37 | } 38 | } 39 | 40 | public static void main(String args[]){ 41 | createString(); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/compile/FinalFlag.java: -------------------------------------------------------------------------------- 1 | package ch11.compile; 2 | 3 | public class FinalFlag { 4 | public static final boolean flag=true; 5 | } 6 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/compile/VarString.java: -------------------------------------------------------------------------------- 1 | package ch11.compile; 2 | 3 | public class VarString { 4 | public static void addString(String str1,String str2){ 5 | String str3=str1+str2; 6 | } 7 | 8 | public static void addString2(String ...str1){ 9 | String str3=""; 10 | for(String str:str1){ 11 | str3+=str1; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inst/Inst2.java: -------------------------------------------------------------------------------- 1 | package ch11.inst; 2 | 3 | public class Inst2 { 4 | public void arraySize() { 5 | int[] a = new int[10]; 6 | System.out.println(a.length); 7 | } 8 | 9 | /** 10 | * if_icmple 11 | */ 12 | public void cmp() { 13 | short f1 = 9; 14 | byte f2 = 10; 15 | System.out.println(f1 > f2); 16 | } 17 | 18 | /** 19 | * fcmpl ifle 20 | */ 21 | public void cmp2() { 22 | float f1 = 9; 23 | float f2 = 10; 24 | System.out.println(f1 > f2); 25 | } 26 | 27 | /** 28 | * if_acmpne if_acmpeq 29 | */ 30 | public void cmp3() { 31 | Object f1 = new Object(); 32 | Object f2 = new Object(); 33 | System.out.println(f1 == f2); 34 | System.out.println(f1 != f2); 35 | } 36 | 37 | /** 38 | * tableswitch 连续 39 | * 40 | * @param i 41 | */ 42 | public void swtich1(int i) { 43 | switch (i) { 44 | case 1:break; 45 | case 2:break; 46 | case 3:break; 47 | } 48 | } 49 | 50 | /** 51 | * lookupswitch 不连续 52 | * 53 | * @param i 54 | */ 55 | public void swtich2(int i) { 56 | switch (i) { 57 | case 100:break; 58 | case 200:break; 59 | case 300:break; 60 | } 61 | } 62 | 63 | /** 64 | * 少数不连续 会编译为连续的tableswitch 65 | * 66 | * @param i 67 | */ 68 | public void swtich3(int i) { 69 | switch (i) { 70 | case 1: 71 | break; 72 | case 2: 73 | break; 74 | case 5: 75 | break; 76 | default: 77 | } 78 | } 79 | 80 | public void swtich4(String i) { 81 | switch (i) { 82 | case "geym": 83 | break; 84 | case "zbase": 85 | break; 86 | case "java": 87 | break; 88 | default: 89 | } 90 | } 91 | 92 | public void trycatch() { 93 | try { 94 | swtich3(1); 95 | } finally { 96 | swtich2(1); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inst/InvokeCode.java: -------------------------------------------------------------------------------- 1 | package ch11.inst; 2 | 3 | import java.util.Date; 4 | 5 | public class InvokeCode { 6 | 7 | private void pMethod(){ 8 | 9 | } 10 | public void invokeVirtual(){ 11 | System.out.println("aa"); 12 | } 13 | 14 | public void invokeSpecial1(){ 15 | Date d=new Date(); 16 | } 17 | public void invokeSpecial2(){ 18 | pMethod(); 19 | } 20 | 21 | public void invokeSpecial3(){ 22 | super.toString(); 23 | } 24 | 25 | public void invokeInterface(){ 26 | Thread t=new Thread(); 27 | t.run(); 28 | ((Runnable)t).run(); 29 | } 30 | 31 | public static interface IAdd{ 32 | long add(long a, long b, long c); 33 | } 34 | public void invokeInterface2(){ 35 | IAdd c=null; 36 | c.add(1, 1,2); 37 | } 38 | 39 | public void invokeStatic(){ 40 | Math.abs(-1); 41 | } 42 | 43 | @Override 44 | public String toString(){ 45 | return ""; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inst/SyncAdd.java: -------------------------------------------------------------------------------- 1 | package ch11.inst; 2 | 3 | public class SyncAdd { 4 | private int i=0; 5 | public synchronized void add1(){ 6 | i++; 7 | } 8 | 9 | public void add2(){ 10 | synchronized(this){ 11 | i++; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/DynBootStrap.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.CallSite; 4 | import java.lang.invoke.ConstantCallSite; 5 | import java.lang.invoke.MethodHandle; 6 | import java.lang.invoke.MethodHandles.Lookup; 7 | import java.lang.invoke.MethodType; 8 | 9 | public class DynBootStrap { 10 | public static CallSite bootstrap(Lookup lookup, String name, MethodType type, Object value) throws Exception { 11 | System.out.println("bootstrap called,name="+name); 12 | MethodHandle mh = lookup.findVirtual(value.getClass(), name, MethodType.methodType(int.class)).bindTo(value); 13 | return new ConstantCallSite(mh); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/FieldMethodHandle.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | 6 | public class FieldMethodHandle { 7 | public static class User{ 8 | public int id; 9 | } 10 | public static void main(String[] args) throws Throwable { 11 | MethodHandles.Lookup lookup = MethodHandles.lookup(); 12 | MethodHandle mh=lookup.findGetter(User.class, "id", int.class); 13 | User u=new User(); 14 | u.id=5; 15 | System.out.println(mh.invoke(u)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/RelectionMain.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodType; 5 | import java.lang.reflect.Method; 6 | 7 | import static java.lang.invoke.MethodHandles.lookup; 8 | 9 | /** 10 | * -Xcomp -XX:-BackgroundCompilation 11 | * 12 | * @author Administrator 13 | * 14 | */ 15 | public class RelectionMain { 16 | public static final int COUNT = 1000000; 17 | int i = 0; 18 | 19 | public void method() { 20 | i++; 21 | } 22 | 23 | public static void callByHandler() throws Throwable { 24 | RelectionMain instance = new RelectionMain(); 25 | MethodType mt = MethodType.methodType(void.class); 26 | MethodHandle mh = lookup().findVirtual(instance.getClass(), "method", mt).bindTo(instance); 27 | long b = System.currentTimeMillis(); 28 | for (int i = 0; i < COUNT; i++) { 29 | mh.invokeExact(); 30 | } 31 | long e = System.currentTimeMillis(); 32 | System.out.println("callByHandler spend:"+(e - b)); 33 | } 34 | 35 | public static void callByReflection() throws Throwable { 36 | RelectionMain instance = new RelectionMain(); 37 | Method m = instance.getClass().getMethod("method"); 38 | long b = System.currentTimeMillis(); 39 | for (int i = 0; i < COUNT; i++) { 40 | m.invoke(instance); 41 | } 42 | long e = System.currentTimeMillis(); 43 | System.out.println("callByReflection spend:"+(e - b)); 44 | } 45 | 46 | public static void main(String[] args) throws Throwable { 47 | callByHandler(); 48 | callByHandler(); 49 | callByReflection(); 50 | callByReflection(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/Simple.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | public class Simple { 4 | 5 | public static void main(String[] args) { 6 | System.out.println(new Object().toString()); 7 | 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/SimpleMethodHandle.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodType; 5 | 6 | import static java.lang.invoke.MethodHandles.lookup; 7 | 8 | public class SimpleMethodHandle { 9 | static class MyPrintln { 10 | protected void println(String s) { 11 | System.out.println(s); 12 | } 13 | } 14 | public static void main(String[] args) throws Throwable { 15 | Object obj = (System.currentTimeMillis() & 1L) == 0L ? System.out : new MyPrintln(); 16 | System.out.println(obj.getClass().toString()); 17 | getPrintlnMethodHandler(obj).invokeExact("geym"); 18 | } 19 | private static MethodHandle getPrintlnMethodHandler(Object receiver) throws Throwable { 20 | MethodType mt = MethodType.methodType(void.class, String.class); 21 | 22 | return lookup().findVirtual(receiver.getClass(), "println", mt).bindTo(receiver); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/SimplePrivateMethodHandle.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | import java.lang.invoke.MethodType; 6 | 7 | /** 8 | * invokeSpecial 9 | * @author Administrator 10 | * 11 | */ 12 | public class SimplePrivateMethodHandle{ 13 | public static void main(String[] args) throws Throwable { 14 | SimplePrivateMethodHandle obj = new SimplePrivateMethodHandle(); 15 | obj.callToString(); 16 | } 17 | 18 | private void printLine() { 19 | System.out.println("call private method"); 20 | } 21 | 22 | public void callToString() throws Throwable { 23 | MethodHandle mh = MethodHandles.lookup().findSpecial(this.getClass(), "printLine", 24 | MethodType.methodType(void.class), this.getClass()).bindTo(this); 25 | mh.invokeExact(); 26 | } 27 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/SimpleStaticMethodHandle.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | import java.lang.invoke.MethodType; 6 | 7 | /** 8 | * invokeSpecial 9 | * @author Administrator 10 | * 11 | */ 12 | public class SimpleStaticMethodHandle{ 13 | public static void main(String[] args) throws Throwable { 14 | SimpleStaticMethodHandle obj = new SimpleStaticMethodHandle(); 15 | System.out.println(obj.callSin()); 16 | } 17 | 18 | public double callSin() throws Throwable { 19 | MethodHandle mh = MethodHandles.lookup().findStatic(Math.class, "sin", 20 | MethodType.methodType(double.class,double.class)); 21 | return (double)mh.invokeExact(Math.PI/2); 22 | } 23 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/SimpleSuperMethodHandle.java: -------------------------------------------------------------------------------- 1 | package ch11.inv; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | import java.lang.invoke.MethodType; 6 | 7 | /** 8 | * invokeSpecial call parent method 9 | * @author Administrator 10 | * 11 | */ 12 | public class SimpleSuperMethodHandle{ 13 | public static void main(String[] args) throws Throwable { 14 | SimpleSuperMethodHandle obj = new SimpleSuperMethodHandle(); 15 | System.out.println(obj.callToString()); 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "I am SimpleSuperMethodHandle"; 21 | } 22 | 23 | public String callToString() throws Throwable { 24 | MethodHandle mh = MethodHandles.lookup().findSpecial(Object.class, "toString", 25 | MethodType.methodType(String.class), this.getClass()).bindTo(this); 26 | String a = (String) mh.invokeExact(); 27 | return a; 28 | } 29 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/dyn/DynBootStrap.java: -------------------------------------------------------------------------------- 1 | package ch11.inv.dyn; 2 | 3 | import java.lang.invoke.CallSite; 4 | import java.lang.invoke.ConstantCallSite; 5 | import java.lang.invoke.MethodHandle; 6 | import java.lang.invoke.MethodHandles.Lookup; 7 | import java.lang.invoke.MethodType; 8 | 9 | public class DynBootStrap { 10 | public static CallSite bootstrap(Lookup lookup, String name, MethodType type,Object handle) throws Exception { 11 | MethodHandle mh0 = lookup.findVirtual(String.class, "substring", MethodType.methodType(String.class,int.class)).bindTo("hello"); 12 | MethodHandle mh = (MethodHandle)handle; 13 | // mh.bindTo("hello"); 14 | // MethodHandle mh = lookup.findVirtual(String.class, "toString", MethodType.methodType(String.class)).bindTo(str); 15 | // MethodHandles.insertArguments(mh, 1, 2); 16 | System.out.println("bootstrap called,name="+name); 17 | System.out.println(handle.getClass().toString()); 18 | 19 | return new ConstantCallSite(mh); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/inv/mtype/DynBootStrap.java: -------------------------------------------------------------------------------- 1 | package ch11.inv.mtype; 2 | 3 | import java.lang.invoke.CallSite; 4 | import java.lang.invoke.ConstantCallSite; 5 | import java.lang.invoke.MethodHandle; 6 | import java.lang.invoke.MethodHandles.Lookup; 7 | import java.lang.invoke.MethodType; 8 | 9 | public class DynBootStrap { 10 | public static CallSite bootstrap(Lookup lookup, String name, MethodType type,Object handle) throws Exception { 11 | MethodHandle mh0 = lookup.findVirtual(String.class, "substring", MethodType.methodType(String.class,int.class)).bindTo("hello"); 12 | 13 | System.out.println("bootstrap called,name="+name); 14 | System.out.println(handle.toString()); 15 | // mh0 16 | return new ConstantCallSite(mh0); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/C1C2TimeMain.java: -------------------------------------------------------------------------------- 1 | package ch11.jit; 2 | 3 | public class C1C2TimeMain { 4 | public static double calcPi(){ 5 | double re=0; 6 | for(int i=1;i<10000;i++){ 7 | re+=((i&1)==0?-1:1)*1.0/(2*i-1); 8 | } 9 | return re*4; 10 | } 11 | public static void main(String[] args) throws InterruptedException { 12 | Thread.sleep(20000); 13 | long b=System.currentTimeMillis(); 14 | for(int i=0;i<10000;i++) 15 | calcPi(); 16 | long e=System.currentTimeMillis(); 17 | System.out.println("spend:"+(e-b)+"ms"); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/IntCompMain.java: -------------------------------------------------------------------------------- 1 | package ch11.jit; 2 | 3 | public class IntCompMain { 4 | public static double calcPi(){ 5 | double re=0; 6 | for(int i=1;i<10000;i++){ 7 | re+=((i&1)==0?-1:1)*1.0/(2*i-1); 8 | } 9 | return re*4; 10 | } 11 | public static void main(String[] args) { 12 | long b=System.currentTimeMillis(); 13 | for(int i=0;i<10000;i++) 14 | calcPi(); 15 | long e=System.currentTimeMillis(); 16 | System.out.println("spend:"+(e-b)+"ms"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/JITSimpleTest.java: -------------------------------------------------------------------------------- 1 | package ch11.jit; 2 | 3 | /** 4 | * -XX:CompileThreshold=1000 -XX:+PrintCompilation 5 | * 6 | * @author Geym 7 | * 8 | */ 9 | public class JITSimpleTest { 10 | 11 | public static void met(){ 12 | int a=0,b=0; 13 | b=a+b; 14 | } 15 | public static void main(String[] args) throws InterruptedException { 16 | for(int i=0;i<500;i++){ 17 | met(); 18 | } 19 | Thread.sleep(1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/JitClassLoader.java: -------------------------------------------------------------------------------- 1 | package ch11.jit; 2 | 3 | public class JitClassLoader extends ClassLoader{ 4 | 5 | } 6 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/Osr.java: -------------------------------------------------------------------------------- 1 | package ch11.jit; 2 | 3 | import static java.lang.Math.pow; 4 | import static java.lang.Math.random; 5 | 6 | /** 7 | * -XX:+PrintCompilation -XX:OnStackReplacePercentage=1000000 -XX:CompileThreshold=1500 8 | * 9 | * -XX:+PrintCompilation -XX:OnStackReplacePercentage=100000 -XX:CompileThreshold=1500 -XX:-BackgroundCompilation -XX:+UseOnStackReplacement -XX:-UseLoopCounter 10 | * @author Administrator 11 | * 12 | */ 13 | public class Osr { 14 | public static double osrMethod() { 15 | double N = 10000000; 16 | int sum = 0; 17 | for (int i=1; i<=N; i++) { 18 | if (pow(random(), 2) + pow(random(),2) < 1) { 19 | sum ++; 20 | } 21 | } 22 | return 4* sum/N; 23 | } 24 | 25 | public static void main(String args[]) { 26 | System.out.println(osrMethod()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/deopt/DBWriter.java: -------------------------------------------------------------------------------- 1 | package ch11.jit.deopt; 2 | 3 | public class DBWriter { 4 | public void write() { 5 | "DBWriter".toCharArray(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/deopt/WriterMain.java: -------------------------------------------------------------------------------- 1 | package ch11.jit.deopt; 2 | 3 | /** 4 | * -XX:+PrintCompilation -client -Xcomp 5 | * -XX:+PrintCompilation -server -Xcomp 查看编译的函数 6 | * -XX:+PrintCompilation -server -Xcomp -XX:+TieredCompilation 编译级别调整 7 | * -XX:+PrintCompilation -server -Xcomp -XX:+TieredCompilation -XX:NmethodSweepFraction=1 大量函数被zombie 8 | * 9 | * @author Administrator 10 | * 11 | */ 12 | public class WriterMain { 13 | public static void main(String[] args) throws InterruptedException { 14 | long b=System.currentTimeMillis(); 15 | WriterService ws=new WriterService(); 16 | for(int i=0;i<20000000;i++){ 17 | ws.service(); 18 | } 19 | long e=System.currentTimeMillis(); 20 | System.out.println("spend:"+(e-b)); 21 | ws=null; 22 | System.gc(); 23 | Thread.sleep(5000); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/deopt/WriterService.java: -------------------------------------------------------------------------------- 1 | package ch11.jit.deopt; 2 | 3 | public class WriterService { 4 | public void service(){ 5 | DBWriter writer=new DBWriter(); 6 | writer.write(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch11/jit/inline/InLineMain.java: -------------------------------------------------------------------------------- 1 | package ch11.jit.inline; 2 | 3 | /** 4 | * @author Administrator 5 | * 6 | */ 7 | public class InLineMain { 8 | static int i=0; 9 | public static void inc(){ 10 | i++; 11 | } 12 | public static void main(String[] args) { 13 | long b=System.currentTimeMillis(); 14 | for(int j=0;j<100000000;j++){ 15 | inc(); 16 | } 17 | long e=System.currentTimeMillis(); 18 | System.out.println(e-b); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch2/SimpleArgs.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | public class SimpleArgs { 4 | public static void main(String[] args) { 5 | for(int i=0;i l=new ArrayList(); 16 | for(int i=0;i<11;i++){ 17 | ByteBuffer b=ByteBuffer.allocateDirect(1024*1024); 18 | l.add(b); 19 | } 20 | long endtime=System.currentTimeMillis(); 21 | System.out.println("testDirectAllocate:"+(endtime-starttime)); 22 | } 23 | 24 | public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, Exception { 25 | AllocBigDirectBuffer alloc=new AllocBigDirectBuffer(); 26 | alloc.testDirectAllocate(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/heap/AllocDirectBuffer.java: -------------------------------------------------------------------------------- 1 | package ch3.heap; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /** 6 | * 直接内存分配较慢 7 | * @author Geym 8 | * 9 | */ 10 | public class AllocDirectBuffer { 11 | public void directAllocate(){ 12 | long starttime=System.currentTimeMillis(); 13 | for(int i=0;i<200000;i++){ 14 | ByteBuffer b=ByteBuffer.allocateDirect(1000); 15 | } 16 | long endtime=System.currentTimeMillis(); 17 | System.out.println("directAllocate:"+(endtime-starttime)); 18 | } 19 | 20 | public void bufferAllocate() { 21 | long starttime=System.currentTimeMillis(); 22 | for(int i=0;i<200000;i++){ 23 | ByteBuffer b=ByteBuffer.allocate(1000); 24 | } 25 | long endtime=System.currentTimeMillis(); 26 | System.out.println("bufferAllocate:"+(endtime-starttime)); 27 | } 28 | 29 | public static void main(String[] args) { 30 | AllocDirectBuffer alloc=new AllocDirectBuffer(); 31 | alloc.bufferAllocate(); 32 | alloc.directAllocate(); 33 | 34 | alloc.bufferAllocate(); 35 | alloc.directAllocate(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/heap/DumpOOM.java: -------------------------------------------------------------------------------- 1 | package ch3.heap; 2 | 3 | import java.util.Vector; 4 | 5 | /** 6 | * -Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump 7 | * 8 | * -Xmx20m -Xms5m "-XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump 9 | * 10 | * printstack.bat: 11 | * D:/tools/jdk1.7_40/bin/jstack -F %1 > D:/a.txt 12 | * @author Geym 13 | * 14 | */ 15 | public class DumpOOM { 16 | public static void main(String[] args) { 17 | Vector v=new Vector(); 18 | for(int i=0;i<25;i++) 19 | v.add(new byte[1*1024*1024]); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/heap/HeapAlloc.java: -------------------------------------------------------------------------------- 1 | package ch3.heap; 2 | 3 | /** 4 | * -Xmx20m -Xms5m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC 5 | * @author Geym 6 | * 7 | */ 8 | public class HeapAlloc { 9 | public static void main(String[] args) { 10 | System.out.print("maxMemory="); 11 | System.out.println(Runtime.getRuntime().maxMemory()+" bytes"); 12 | System.out.print("free mem="); 13 | System.out.println(Runtime.getRuntime().freeMemory()+" bytes"); 14 | System.out.print("total mem="); 15 | System.out.println(Runtime.getRuntime().totalMemory()+" bytes"); 16 | 17 | byte[] b=new byte[1*1024*1024]; 18 | System.out.println("分配了1M空间给数组"); 19 | 20 | System.out.print("maxMemory="); 21 | System.out.println(Runtime.getRuntime().maxMemory()+" bytes"); 22 | System.out.print("free mem="); 23 | System.out.println(Runtime.getRuntime().freeMemory()+" bytes"); 24 | System.out.print("total mem="); 25 | System.out.println(Runtime.getRuntime().totalMemory()+" bytes"); 26 | 27 | b=new byte[4*1024*1024]; 28 | System.out.println("分配了4M空间给数组"); 29 | 30 | System.out.print("maxMemory="); 31 | System.out.println(Runtime.getRuntime().maxMemory()+" bytes"); 32 | System.out.print("free mem="); 33 | System.out.println(Runtime.getRuntime().freeMemory()+" bytes"); 34 | System.out.print("total mem="); 35 | System.out.println(Runtime.getRuntime().totalMemory()+" bytes"); 36 | } 37 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/heap/newsize/NewSizeDemo.java: -------------------------------------------------------------------------------- 1 | 2 | package ch3.heap.newsize; 3 | 4 | /** 5 | * -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails 6 | * -Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails 7 | * -Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 -XX:+PrintGCDetails 8 | * 9 | * -Xmx20M -Xms20M -XX:NewRatio=2 -XX:+PrintGCDetails 10 | * 11 | * @author Geym 12 | */ 13 | public class NewSizeDemo { 14 | public static void main(String[] args) { 15 | byte[] b=null; 16 | for(int i=0;i<10;i++) 17 | b=new byte[1*1024*1024]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/heap/newsize/NewSizeRatio.java: -------------------------------------------------------------------------------- 1 | package ch3.heap.newsize; 2 | /** 3 | * -Xmx20m -Xms20m -XX:NewRatio=1 -XX:SurvivorRatio=2 -XX:+PrintGCDetails 4 | * @author Geym 5 | * 6 | */ 7 | public class NewSizeRatio { 8 | 9 | public static void main(String[] args) { 10 | byte[] b=null; 11 | for(int i=0;i<10;i++) 12 | b=new byte[1*1024*1024]; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/trace/SimpleGc.java: -------------------------------------------------------------------------------- 1 | package ch3.trace; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * -verbose:gc 8 | * -XX:+PrintGC 9 | * -XX:+PrintGCDetails 10 | * -XX:+PrintGCTimeStamps 11 | * -XX:+PrintGCApplicationConcurrentTime 12 | * -XX:+PrintGCApplicationStoppedTime 13 | * 14 | * -XX:+PrintReferenceGC 15 | * 16 | * -XX:+PrintHeapAtGC 17 | * 18 | * -XX:+PrintVMOptions -XX:+PrintCommandLineFlags 19 | * -XX:+PrintFlagsFinal ��ӡ���� 20 | * 21 | * -Xloggc:log/gc.log 22 | * @author geym 23 | * 24 | */ 25 | public class SimpleGc { 26 | public static void main(String[] args) { 27 | List l=new ArrayList(); 28 | for(int i=0;i<1000000;i++){ 29 | byte[] bytes= new byte[64]; 30 | l.add(bytes); 31 | if(l.size()*64/1024/1024>13){ 32 | l.clear(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/trace/UnloadClass.java: -------------------------------------------------------------------------------- 1 | package ch3.trace; 2 | 3 | import org.objectweb.asm.ClassWriter; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | 10 | /** 11 | * -XX:+TraceClassUnloading -XX:+TraceClassLoading 12 | * 13 | * -verbose:class 14 | * @author Administrator 15 | * 16 | */ 17 | public class UnloadClass implements Opcodes{ 18 | public static void main(String args[]) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 19 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); 20 | cw.visit(V1_7, ACC_PUBLIC, "Example", null, "java/lang/Object", null); 21 | MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); 22 | mw.visitVarInsn(ALOAD, 0); 23 | mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); 24 | mw.visitInsn(RETURN); 25 | mw.visitMaxs(0, 0); 26 | mw.visitEnd(); 27 | mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); 28 | mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 29 | mw.visitLdcInsn("Hello world!"); 30 | mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 31 | mw.visitInsn(RETURN); 32 | mw.visitMaxs(0, 0); 33 | mw.visitEnd(); 34 | byte[] code = cw.toByteArray(); 35 | 36 | for(int i=0;i<10;i++){ 37 | UnloadClassLoader loader = new UnloadClassLoader(); 38 | Method m=ClassLoader.class.getDeclaredMethod("defineClass", String.class,byte[].class,int.class,int.class); 39 | m.setAccessible(true); 40 | m.invoke(loader, "Example", code, 0, code.length); 41 | m.setAccessible(false); 42 | System.gc(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/trace/UnloadClassLoader.java: -------------------------------------------------------------------------------- 1 | package ch3.trace; 2 | 3 | public class UnloadClassLoader extends ClassLoader { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch3/xss/TestStackDeep.java: -------------------------------------------------------------------------------- 1 | package ch3.xss; 2 | 3 | /** 4 | * -Xss1m 5 | * @author Administrator 6 | * 7 | */ 8 | public class TestStackDeep { 9 | private static int count=0; 10 | public static void recursion(long a,long b,long c){ 11 | long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10; 12 | count++; 13 | recursion(a,b,c); 14 | } 15 | public static void main(String args[]){ 16 | try{ 17 | recursion(0L,0L,0L); 18 | }catch(Throwable e){ 19 | System.out.println("deep of calling = "+count); 20 | e.printStackTrace(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/ref/CanReliveObj.java: -------------------------------------------------------------------------------- 1 | package ch4.ref; 2 | 3 | public class CanReliveObj { 4 | public static CanReliveObj obj; 5 | @Override 6 | protected void finalize() throws Throwable { 7 | super.finalize(); 8 | System.out.println("CanReliveObj finalize called"); 9 | obj=this; 10 | } 11 | @Override 12 | public String toString(){ 13 | return "I am CanReliveObj"; 14 | } 15 | public static void main(String[] args) throws InterruptedException{ 16 | obj=new CanReliveObj(); 17 | obj=null; 18 | System.gc(); 19 | Thread.sleep(1000); 20 | if(obj==null){ 21 | System.out.println("obj 是 null"); 22 | }else{ 23 | System.out.println("obj 可用"); 24 | } 25 | System.out.println("第二次gc"); 26 | obj=null; 27 | System.gc(); 28 | Thread.sleep(1000); 29 | if(obj==null){ 30 | System.out.println("obj 是 null"); 31 | }else{ 32 | System.out.println("obj 可用"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/ref/SoftRef.java: -------------------------------------------------------------------------------- 1 | package ch4.ref; 2 | 3 | import java.lang.ref.SoftReference; 4 | 5 | /** 6 | * -Xmx10m 7 | * After gc, soft ref is exists 8 | * after create byte array ,soft ref is gc 9 | * 10 | * @author geym 11 | * 12 | */ 13 | public class SoftRef { 14 | public static class User{ 15 | public User(int id,String name){ 16 | this.id=id; 17 | this.name=name; 18 | } 19 | public int id; 20 | public String name; 21 | 22 | @Override 23 | public String toString(){ 24 | return "[id="+String.valueOf(id)+",name="+name+"]"; 25 | } 26 | } 27 | public static void main(String[] args) { 28 | User u=new User(1,"geym"); 29 | SoftReference userSoftRef = new SoftReference(u); 30 | u=null; 31 | 32 | System.out.println(userSoftRef.get()); 33 | System.gc(); 34 | System.out.println("After GC:"); 35 | System.out.println(userSoftRef.get()); 36 | 37 | byte[] b=new byte[1024*925*7]; 38 | System.gc(); 39 | System.out.println(userSoftRef.get()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/ref/TraceCanReliveObj.java: -------------------------------------------------------------------------------- 1 | package ch4.ref; 2 | 3 | 4 | import java.lang.ref.PhantomReference; 5 | import java.lang.ref.ReferenceQueue; 6 | 7 | /** 8 | * finalize 是不可靠的 9 | * 虚引用是可靠的 10 | * @author geym 11 | * 12 | */ 13 | public class TraceCanReliveObj { 14 | public static TraceCanReliveObj obj; 15 | static ReferenceQueue phantomQueue=null; 16 | public static class CheckRefQueue extends Thread{ 17 | @Override 18 | public void run(){ 19 | while(true){ 20 | if(phantomQueue!=null){ 21 | PhantomReference objt=null; 22 | try { 23 | objt = (PhantomReference)phantomQueue.remove(); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | if(objt!=null){ 28 | System.out.println("TraceCanReliveObj is delete by GC"); 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | @Override 36 | protected void finalize() throws Throwable { 37 | super.finalize(); 38 | System.out.println("CanReliveObj finalize called"); 39 | obj=this; 40 | } 41 | @Override 42 | public String toString(){ 43 | return "I am CanReliveObj"; 44 | } 45 | public static void main(String[] args) throws InterruptedException{ 46 | Thread t=new CheckRefQueue(); 47 | t.setDaemon(true); 48 | t.start(); 49 | 50 | phantomQueue = new ReferenceQueue(); 51 | obj=new TraceCanReliveObj(); 52 | PhantomReference phantomRef = new PhantomReference(obj,phantomQueue); 53 | 54 | obj=null; 55 | System.gc(); 56 | Thread.sleep(1000); 57 | if(obj==null){ 58 | System.out.println("obj 是 null"); 59 | }else{ 60 | System.out.println("obj 可用"); 61 | } 62 | System.out.println("第二次gc"); 63 | obj=null; 64 | System.gc(); 65 | Thread.sleep(1000); 66 | if(obj==null){ 67 | System.out.println("obj 是 null"); 68 | }else{ 69 | System.out.println("obj 可用"); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/ref/WeakRef.java: -------------------------------------------------------------------------------- 1 | package ch4.ref; 2 | 3 | import java.lang.ref.WeakReference; 4 | 5 | /** 6 | * 不管当前内存空间足够与否,都会回收它的内存 7 | * @author geym 8 | * 9 | */ 10 | public class WeakRef { 11 | public static class User{ 12 | public User(int id,String name){ 13 | this.id=id; 14 | this.name=name; 15 | } 16 | public int id; 17 | public String name; 18 | 19 | @Override 20 | public String toString(){ 21 | return "[id="+String.valueOf(id)+",name="+name+"]"; 22 | } 23 | } 24 | public static void main(String[] args) { 25 | User u=new User(1,"geym"); 26 | WeakReference userWeakRef = new WeakReference(u); 27 | u=null; 28 | System.out.println(userWeakRef.get()); 29 | System.gc(); 30 | //不管当前内存空间足够与否,都会回收它的内存 31 | System.out.println("After GC:"); 32 | System.out.println(userWeakRef.get()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/stw/StopWorldTest.java: -------------------------------------------------------------------------------- 1 | package ch4.stw; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * @author Administrator 7 | * 8 | */ 9 | public class StopWorldTest { 10 | public static class MyThread extends Thread{ 11 | HashMap map=new HashMap(); 12 | @Override 13 | public void run(){ 14 | try{ 15 | while(true){ 16 | if(map.size()*512/1024/1024>=900){ 17 | map.clear(); 18 | System.out.println("clean map"); 19 | } 20 | byte[] b1; 21 | for(int i=0;i<100;i++){ 22 | b1=new byte[512]; 23 | map.put(System.nanoTime(), b1); 24 | } 25 | Thread.sleep(1); 26 | } 27 | }catch(Exception e){ 28 | 29 | } 30 | } 31 | } 32 | public static class PrintThread extends Thread{ 33 | public static final long starttime=System.currentTimeMillis(); 34 | @Override 35 | public void run(){ 36 | try{ 37 | while(true){ 38 | long t=System.currentTimeMillis()-starttime; 39 | System.out.println(t/1000+"."+t%1000); 40 | Thread.sleep(100); 41 | } 42 | }catch(Exception e){ 43 | 44 | } 45 | } 46 | } 47 | public static void main(String args[]){ 48 | MyThread t=new MyThread(); 49 | PrintThread p=new PrintThread(); 50 | t.start(); 51 | p.start(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch4/stw/StopWorldTest_MinorGC.java: -------------------------------------------------------------------------------- 1 | package ch4.stw; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * @author Administrator 7 | * 8 | */ 9 | public class StopWorldTest_MinorGC { 10 | public static class MyThread extends Thread{ 11 | HashMap map=new HashMap(); 12 | @Override 13 | public void run(){ 14 | try{ 15 | while(true){ 16 | if(map.size()*512/1024/1024>=550){ 17 | map.clear(); 18 | System.out.println("clean map"); 19 | } 20 | byte[] b1; 21 | for(int i=0;i<100;i++){ 22 | b1=new byte[512]; 23 | map.put(System.nanoTime(), b1); 24 | } 25 | Thread.sleep(1); 26 | } 27 | }catch(Exception e){ 28 | 29 | } 30 | } 31 | } 32 | public static class PrintThread extends Thread{ 33 | public static final long starttime=System.currentTimeMillis(); 34 | @Override 35 | public void run(){ 36 | try{ 37 | while(true){ 38 | long t=System.currentTimeMillis()-starttime; 39 | System.out.println(t/1000+"."+t%1000); 40 | Thread.sleep(100); 41 | } 42 | }catch(Exception e){ 43 | 44 | } 45 | } 46 | } 47 | public static void main(String args[]){ 48 | MyThread t=new MyThread(); 49 | PrintThread p=new PrintThread(); 50 | t.start(); 51 | p.start(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/AllocEden.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | /** 4 | * 5 | * -Xmx64M -Xms64M -XX:+PrintGCDetails 6 | * @author geym 7 | * 8 | */ 9 | public class AllocEden { 10 | public static final int _1K=1024; 11 | public static void main(String args[]){ 12 | for(int i=0;i<5*_1K;i++){ 13 | byte[] b=new byte[_1K]; 14 | } 15 | System.gc(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/BigObject.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 8 | *-Xmx10M -Xms10M -Xmn1m -XX:+PrintGCDetails 9 | * 新生代太小,大对象直接晋升 10 | * 11 | * 12 | * @author geym 13 | * 14 | */ 15 | public class BigObject { 16 | public static final int _100K=1024*100; 17 | public static void main(String args[]){ 18 | Map map=new HashMap(); 19 | for(int i=0;i<5;i++){ 20 | byte[] b=new byte[_100K]; 21 | map.put(i, b); 22 | } 23 | // System.gc(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/ComputeTenuringThreshold.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author geym 8 | * 9 | */ 10 | public class ComputeTenuringThreshold { 11 | public static final int _1M=1024*1024; 12 | public static final int _1K=1024; 13 | public static void main(String args[]){ 14 | Map map=new HashMap(); 15 | 16 | for(int i=0;i<5*_1K;i++){ 17 | byte[] b=new byte[_1K]; 18 | map.put(i, b); 19 | } 20 | 21 | //触发新生代GC 22 | for(int k=0;k<17;k++){ 23 | for(int i=0;i<270;i++){ 24 | byte[] g=new byte[_1M]; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/DisableExplictGC.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | /** 4 | * -XX:+PrintGCDetails -XX:-DisableExplicitGC 5 | * @author geym 6 | * 7 | */ 8 | public class DisableExplictGC { 9 | public static void main(String args[]){ 10 | while(true){ 11 | System.gc(); 12 | Thread.yield(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/ExplicitGCInvokesConcurrent.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | /** 4 | * -XX:+PrintGCDetails -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC 5 | * -XX:+PrintGCDetails -XX:+ExplicitGCInvokesConcurrent -XX:+UseG1GC 6 | * 7 | * ExplicitGCInvokesConcurrent 在System.gc()时会使用并发方式 回收 8 | * @author geym 9 | * 10 | */ 11 | public class ExplicitGCInvokesConcurrent { 12 | public static void main(String args[]){ 13 | while(true){ 14 | System.gc(); 15 | Thread.yield(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/LongFinalize.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | 4 | /** 5 | * 有了一个慢的finalize()会导致无法回收 6 | * 7 | * -Xmx10m -Xms10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="D:/f.dump" 8 | * @author Administrator 9 | * 10 | */ 11 | public class LongFinalize { 12 | public static class LF { 13 | private byte[] content =new byte[512]; 14 | @Override 15 | protected void finalize(){ 16 | try { 17 | System.out.println(Thread.currentThread().getId()); 18 | Thread.sleep(1000); 19 | } catch (Exception e) { 20 | e.printStackTrace(); 21 | } 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws InterruptedException { 26 | long b=System.currentTimeMillis(); 27 | for(int i=0;i<50000;i++){ 28 | LF f=new LF(); 29 | Thread.sleep(1); 30 | } 31 | long e=System.currentTimeMillis(); 32 | System.out.println(e-b); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/MaxTenuringThreshold.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 最大的晋升年龄 8 | * MaxTenuringThreshold 默认值15 9 | * 10 | * -Xmx1024M -Xms1024M -XX:+PrintGCDetails -XX:MaxTenuringThreshold=15 -XX:+PrintHeapAtGC 11 | * 12 | * @author geym 13 | * 14 | */ 15 | public class MaxTenuringThreshold { 16 | public static final int _1M=1024*1024; 17 | public static final int _1K=1024; 18 | public static void main(String args[]){ 19 | Map map=new HashMap(); 20 | for(int i=0;i<5*_1K;i++){ 21 | byte[] b=new byte[_1K]; 22 | map.put(i, b); 23 | } 24 | 25 | for(int k=0;k<17;k++){ 26 | for(int i=0;i<270;i++){ 27 | byte[] g=new byte[_1M]; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/PretenureSizeThreshold.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 超过给定大小的对象直接晋升 8 | * -Xmx32m -Xms32m -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 9 | * 必须禁止TLAB,否则小对象依然会在eden区 10 | * -Xmx32m -Xms32m -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB 11 | * @author geym 12 | * 13 | */ 14 | public class PretenureSizeThreshold { 15 | public static final int _1K=1024; 16 | public static void main(String args[]){ 17 | Map map=new HashMap(); 18 | for(int i=0;i<5*_1K;i++){ 19 | byte[] b=new byte[_1K]; 20 | map.put(i, b); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/ScavengeBeforeFullGC.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | 4 | /** 5 | * -XX:+PrintGCDetails -XX:-ScavengeBeforeFullGC -XX:+UseParallelOldGC 6 | * 7 | * 8 | * -XX:+PrintGCDetails -XX:+UseSerialGC 9 | * @author geym 10 | * 11 | */ 12 | public class ScavengeBeforeFullGC { 13 | public static void main(String args[]){ 14 | System.gc(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/UseTLAB.java: -------------------------------------------------------------------------------- 1 | package ch5; 2 | 3 | /** 4 | * 5 | * 测试速度 6 | * -XX:-UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis -server 7 | * 8 | * -XX:+UseTLAB -Xcomp -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis -server 9 | * 10 | * 测试日志 11 | * -XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=307200 -XX:-ResizeTLAB 12 | * 13 | * 使用 XX:TLABRefillWasteFraction 改变refill waste 14 | * -XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=102400 -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=100 -XX:-DoEscapeAnalysis -server 15 | * @author geym 16 | * 17 | */ 18 | public class UseTLAB { 19 | public static void alloc(){ 20 | byte[] b=new byte[2]; 21 | b[0]=1; 22 | 23 | } 24 | public static void main(String args[]){ 25 | long b=System.currentTimeMillis(); 26 | for(int i=0;i<10000000;i++){ 27 | alloc(); 28 | } 29 | long e=System.currentTimeMillis(); 30 | System.out.println(e-b); 31 | } 32 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/cms/CMSTest.java: -------------------------------------------------------------------------------- 1 | package ch5.cms; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * -Xmx200m -Xms200m -XX:+UseConcMarkSweepGC -Xloggc:gc.log -XX:+PrintGCDetails 7 | * @author Administrator 8 | * 9 | */ 10 | public class CMSTest { 11 | public static class MyThread extends Thread{ 12 | HashMap map=new HashMap(); 13 | @Override 14 | public void run(){ 15 | try{ 16 | while(true){ 17 | byte[] b1; 18 | if(map.size()*512/1024/1024>=200){ 19 | map.clear(); 20 | 21 | System.out.println("clean map2"); 22 | } 23 | for(int i=0;i<1000;i++){ 24 | b1=new byte[512]; 25 | map.put(System.nanoTime(), b1); 26 | for(int j=0;j<1000;j++){ 27 | byte[] b2=new byte[10]; 28 | } 29 | } 30 | Thread.sleep(1); 31 | } 32 | }catch(Exception e){ 33 | 34 | } 35 | } 36 | } 37 | public static class PrintThread extends Thread{ 38 | public static final long starttime=System.currentTimeMillis(); 39 | @Override 40 | public void run(){ 41 | try{ 42 | while(true){ 43 | long t=System.currentTimeMillis()-starttime; 44 | System.out.println(t/1000+"."+t%1000); 45 | Thread.sleep(100); 46 | // byte[] b=new byte[1024*1024*3]; 47 | } 48 | }catch(Exception e){ 49 | 50 | } 51 | } 52 | } 53 | public static void main(String args[]){ 54 | MyThread t=new MyThread(); 55 | PrintThread p=new PrintThread(); 56 | t.start(); 57 | p.start(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/g1/G1Test.java: -------------------------------------------------------------------------------- 1 | package ch5.g1; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * -Xmx200m -Xms200m -XX:+UseG1GC -Xloggc:gc.log -XX:+PrintGCDetails -XX:MaxGCPauseMillis=2000 -XX:+PrintTenuringDistribution 7 | * @author Administrator 8 | * 9 | */ 10 | public class G1Test { 11 | public static class MyThread extends Thread{ 12 | HashMap map=new HashMap(); 13 | @Override 14 | public void run(){ 15 | try{ 16 | while(true){ 17 | byte[] b1; 18 | if(map.size()*512/1024/1024>=200){ 19 | map.clear(); 20 | 21 | System.out.println("clean map"); 22 | } 23 | for(int i=0;i<1000;i++){ 24 | b1=new byte[512]; 25 | map.put(System.nanoTime(), b1); 26 | for(int j=0;j<1000;j++){ 27 | byte[] b2=new byte[10]; 28 | } 29 | } 30 | Thread.sleep(1); 31 | } 32 | }catch(Exception e){ 33 | 34 | } 35 | } 36 | } 37 | public static class PrintThread extends Thread{ 38 | public static final long starttime=System.currentTimeMillis(); 39 | @Override 40 | public void run(){ 41 | try{ 42 | while(true){ 43 | long t=System.currentTimeMillis()-starttime; 44 | System.out.println(t/1000+"."+t%1000); 45 | Thread.sleep(100); 46 | // byte[] b=new byte[1024*1024*3]; 47 | } 48 | }catch(Exception e){ 49 | 50 | } 51 | } 52 | } 53 | public static void main(String args[]){ 54 | MyThread t=new MyThread(); 55 | PrintThread p=new PrintThread(); 56 | t.start(); 57 | p.start(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/noclassgc/CglibBean.java: -------------------------------------------------------------------------------- 1 | package ch5.noclassgc; 2 | 3 | import net.sf.cglib.core.NamingPolicy; 4 | import net.sf.cglib.core.Predicate; 5 | 6 | import java.util.Iterator; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | public class CglibBean { 11 | /** 12 | * 实体Object 13 | */ 14 | public Object object = null; 15 | 16 | 17 | public CglibBean() { 18 | super(); 19 | } 20 | 21 | 22 | public CglibBean(String className,Map propertyMap) { 23 | this.object = generateBean(className,propertyMap); 24 | } 25 | 26 | 27 | /** 28 | * 得到该实体bean对象 29 | * 30 | * @return 31 | */ 32 | public Object getObject() { 33 | return this.object; 34 | } 35 | 36 | private Object generateBean(final String className,Map propertyMap) { 37 | BeanGeneratorObj generator = new BeanGeneratorObj(); 38 | generator.setUseCache(false); 39 | generator.setClassLoader(new ClassLoader(){ 40 | 41 | }); 42 | generator.setNamingPolicy(new NamingPolicy() { 43 | 44 | public String getClassName(String prefix, String source, Object key, Predicate names) { 45 | return className; 46 | } 47 | }); 48 | 49 | Set keySet = propertyMap.keySet(); 50 | for (Iterator i = keySet.iterator(); i.hasNext();) { 51 | String key = (String) i.next(); 52 | generator.addProperty(key, (Class) propertyMap.get(key)); 53 | } 54 | return generator.create(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch5/noclassgc/PermTest.java: -------------------------------------------------------------------------------- 1 | package ch5.noclassgc; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * noclassgc 不会回收perm 7 | *-XX:+PrintGCDetails -XX:PermSize=5M -XX:MaxPermSize=5m -verbose:class -Xnoclassgc 8 | * 9 | * Perm默认不用CMS,加了CMSClassUnloadingEnabled启用CMS回收Perm 10 | * -XX:+PrintGCDetails -XX:PermSize=5M -XX:MaxPermSize=5m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 11 | * @author Geym 12 | * 13 | */ 14 | public class PermTest { 15 | 16 | public static void main(String[] args) { 17 | for(int i=0;i<100000;i++){ 18 | CglibBean bean = new CglibBean("geym.zbase.ch5.perm"+i,new HashMap()); 19 | } 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/HoldNetMain_BTrace.java: -------------------------------------------------------------------------------- 1 | package ch6; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.net.URL; 8 | import java.net.URLConnection; 9 | 10 | /** 11 | * @author Geym 12 | * 13 | */ 14 | public class HoldNetMain_BTrace { 15 | public static class HoldNetTask implements Runnable { 16 | public void visitWeb(String strUrl){ 17 | URL url = null; 18 | URLConnection urlcon = null; 19 | InputStream is = null; 20 | try { 21 | url = new URL(strUrl); 22 | urlcon = url.openConnection(); 23 | is = urlcon.getInputStream(); 24 | BufferedReader buffer = new BufferedReader(new InputStreamReader(is)); 25 | StringBuffer bs = new StringBuffer(); 26 | String l = null; 27 | while ((l = buffer.readLine()) != null) { 28 | bs.append(l).append("\r\n"); 29 | } 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } finally { 33 | if (is != null) { 34 | try { 35 | is.close(); 36 | } catch (IOException e) { 37 | } 38 | } 39 | } 40 | } 41 | 42 | public void run() { 43 | while (true) { 44 | visitWeb("http://www.sina.com.cn"); 45 | } 46 | } 47 | } 48 | 49 | public static class LazyTask implements Runnable { 50 | public void run() { 51 | try { 52 | while (true) { 53 | Thread.sleep(1000); 54 | } 55 | } catch (Exception e) { 56 | 57 | } 58 | } 59 | } 60 | 61 | public static void main(String[] args) { 62 | new Thread(new HoldNetTask()).start(); 63 | new Thread(new LazyTask()).start(); 64 | new Thread(new LazyTask()).start(); 65 | new Thread(new LazyTask()).start(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/UseTlab.java: -------------------------------------------------------------------------------- 1 | package ch6; 2 | 3 | public class UseTlab { 4 | public static void alloc(){ 5 | byte[] b=new byte[2]; 6 | b[0]=1; 7 | 8 | } 9 | public static void main(String args[]){ 10 | while(true){ 11 | alloc(); 12 | Thread.yield(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/hold/DeadLock.java: -------------------------------------------------------------------------------- 1 | package ch6.hold; 2 | 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | public class DeadLock extends Thread{ 6 | protected Object myDirect; 7 | static ReentrantLock south = new ReentrantLock(); 8 | static ReentrantLock north = new ReentrantLock(); 9 | 10 | public DeadLock(Object obj){ 11 | this.myDirect=obj; 12 | if(myDirect==south){ 13 | this.setName("south"); 14 | } 15 | if(myDirect==north){ 16 | this.setName("north"); 17 | } 18 | } 19 | @Override 20 | public void run() { 21 | if (myDirect == south) { 22 | try { 23 | north.lockInterruptibly(); 24 | try { 25 | Thread.sleep(500); 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | south.lockInterruptibly(); 30 | System.out.println("car to south has passed"); 31 | } catch (InterruptedException e1) { 32 | System.out.println("car to south is killed"); 33 | }finally{ 34 | if(north.isHeldByCurrentThread()) 35 | north.unlock(); 36 | if(south.isHeldByCurrentThread()) 37 | south.unlock(); 38 | } 39 | 40 | } 41 | if (myDirect == north) { 42 | try { 43 | south.lockInterruptibly(); 44 | try { 45 | Thread.sleep(500); 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | } 49 | north.lockInterruptibly(); 50 | System.out.println("car to north has passed"); 51 | } catch (InterruptedException e1) { 52 | System.out.println("car to north is killed"); 53 | }finally{ 54 | if(north.isHeldByCurrentThread()) 55 | north.unlock(); 56 | if(south.isHeldByCurrentThread()) 57 | south.unlock(); 58 | } 59 | 60 | } 61 | } 62 | 63 | public static void main(String[] args) throws InterruptedException { 64 | DeadLock car2south = new DeadLock(south); 65 | DeadLock car2north = new DeadLock(north); 66 | car2south.start(); 67 | car2north.start(); 68 | Thread.sleep(1000); 69 | } 70 | } -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/hold/HProfTest.java: -------------------------------------------------------------------------------- 1 | package ch6.hold; 2 | 3 | public class HProfTest { 4 | public void slowMethod() 5 | { 6 | try { 7 | Thread.sleep( 1000 ); //模拟一个很慢的方法 8 | } catch (InterruptedException e) { 9 | e.printStackTrace(); } 10 | } 11 | 12 | public void slowerMethod() 13 | { 14 | try { 15 | Thread.sleep( 10000 ); //模拟一个更慢的方法 16 | } catch (InterruptedException e) { 17 | e.printStackTrace(); } 18 | } 19 | 20 | public void fastMethod() //一个很快的方法 21 | { 22 | try { 23 | Thread.yield(); 24 | } catch (Exception e) { 25 | e.printStackTrace(); } 26 | } 27 | 28 | public static void main( String[] args ) 29 | { 30 | HProfTest test = new HProfTest(); 31 | test.fastMethod(); //分别运行这些方法 32 | test.slowMethod(); 33 | test.slowerMethod(); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/hold/HoldCPUMain.java: -------------------------------------------------------------------------------- 1 | package ch6.hold; 2 | 3 | 4 | public class HoldCPUMain { 5 | public static class HoldCPUTask implements Runnable{ 6 | 7 | public void run() { 8 | while(true){ 9 | double a=Math.random()*Math.random(); 10 | } 11 | } 12 | } 13 | public static class LazyTask implements Runnable{ 14 | public void run(){ 15 | try{ 16 | while(true){ 17 | Thread.sleep(1000); 18 | } 19 | }catch(Exception e){ 20 | 21 | } 22 | } 23 | } 24 | 25 | public static void main(String[] args){ 26 | new Thread(new HoldCPUTask()).start(); 27 | new Thread(new LazyTask()).start(); 28 | new Thread(new LazyTask()).start(); 29 | new Thread(new LazyTask()).start(); 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/hold/HoldIOMain.java: -------------------------------------------------------------------------------- 1 | package ch6.hold; 2 | 3 | 4 | import java.io.*; 5 | 6 | public class HoldIOMain { 7 | public static class HoldIOTask implements Runnable{ 8 | public void run() { 9 | while(true){ 10 | try { 11 | FileOutputStream fos=new FileOutputStream(new File("temp")); 12 | for(int i=0;i<10000;i++) 13 | fos.write(i); 14 | fos.close(); 15 | FileInputStream fis=new FileInputStream(new File("temp")); 16 | while(fis.read()!=-1); 17 | System.out.println("once ag"); 18 | } catch (FileNotFoundException e) { 19 | e.printStackTrace(); 20 | } catch (IOException e) { 21 | e.printStackTrace(); 22 | } 23 | } 24 | } 25 | } 26 | public static class LazyTask implements Runnable{ 27 | public void run(){ 28 | try{ 29 | while(true){ 30 | Thread.sleep(1000); 31 | } 32 | }catch(Exception e){ 33 | 34 | } 35 | } 36 | } 37 | 38 | public static void main(String[] args){ 39 | new Thread(new HoldIOTask()).start(); 40 | new Thread(new LazyTask()).start(); 41 | new Thread(new LazyTask()).start(); 42 | new Thread(new LazyTask()).start(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch6/hold/HoldLockMain.java: -------------------------------------------------------------------------------- 1 | package ch6.hold; 2 | 3 | public class HoldLockMain { 4 | public static Object[] lock=new Object[10]; 5 | public static java.util.Random r=new java.util.Random(); 6 | static{ 7 | for(int i=0;i map=new WeakHashMap(); 19 | 20 | public void run() { 21 | try{ 22 | while(true){ 23 | map.put(System.nanoTime(), new byte[512]); 24 | Thread.sleep(1); 25 | } 26 | }catch(Exception e){ 27 | 28 | } 29 | } 30 | } 31 | 32 | public static void main(String[] args){ 33 | new Thread(new HoldMemoryTask()).start(); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/heap/Student.java: -------------------------------------------------------------------------------- 1 | package ch7.heap; 2 | 3 | import java.util.List; 4 | import java.util.Vector; 5 | 6 | public class Student { 7 | private int id; 8 | private String name; 9 | private List history=new Vector(); 10 | 11 | public Student(int id, String name) { 12 | super(); 13 | this.id = id; 14 | this.name = name; 15 | } 16 | 17 | public int getId() { 18 | return id; 19 | } 20 | public void setId(int id) { 21 | this.id = id; 22 | } 23 | public String getName() { 24 | return name; 25 | } 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public void visit(WebPage w){ 31 | history.add(w); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/heap/TraceStudent.java: -------------------------------------------------------------------------------- 1 | 2 | package ch7.heap; 3 | 4 | import java.util.List; 5 | import java.util.Vector; 6 | 7 | /** 8 | * dump the heap 9 | * -XX:+HeapDumpBeforeFullGC -XX:HeapDumpPath=D:/stu.hprof 10 | * @author geym 11 | * 12 | */ 13 | public class TraceStudent { 14 | 15 | static List webpages = new Vector(); 16 | 17 | public static void createWebPages() { 18 | for (int i = 0; i < 100; i++) { 19 | WebPage wp = new WebPage(); 20 | wp.setUrl("http://www." + Integer.toString(i) + ".com"); 21 | wp.setContent(Integer.toString(i)); 22 | webpages.add(wp); 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | createWebPages(); 28 | Student st3 = new Student(3, "billy"); 29 | Student st5 = new Student(5, "alice"); 30 | Student st7 = new Student(7, "taotao"); 31 | for (int i = 0; i < webpages.size(); i++) { 32 | if (i % st3.getId() == 0) 33 | st3.visit(webpages.get(i)); 34 | if (i % st5.getId() == 0) 35 | st5.visit(webpages.get(i)); 36 | if (i % st7.getId() == 0) 37 | st7.visit(webpages.get(i)); 38 | } 39 | 40 | webpages.clear(); 41 | System.gc(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/heap/WebPage.java: -------------------------------------------------------------------------------- 1 | package ch7.heap; 2 | 3 | public class WebPage { 4 | private String url; 5 | private String content; 6 | 7 | public String getUrl() { 8 | return url; 9 | } 10 | public void setUrl(String url) { 11 | this.url = url; 12 | } 13 | public String getContent() { 14 | return content; 15 | } 16 | public void setContent(String cotent) { 17 | this.content = cotent; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/oom/DirectBufferOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.oom; 2 | 3 | import java.nio.ByteBuffer; 4 | /** 5 | * -Xmx512m -XX:+PrintGCDetails ok 6 | * -Xmx1g -XX:+PrintGCDetails OOM 强制GC可以 7 | * DirectBuffer到达-XX:MaxDirectMemorySize之前, 8 | * java不会由DirectBuffer来触发GC,但是在GC时会回收DirectBuffer 9 | * @author Geym 10 | * 11 | */ 12 | public class DirectBufferOOM { 13 | public static void main(String args[]){ 14 | for(int i=0;i<1024;i++){ 15 | ByteBuffer.allocateDirect(1024*1024); 16 | System.out.println(i); 17 | // System.gc(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/oom/MultiThreadOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.oom; 2 | 3 | /** 4 | * 5 | * 内存越少 线程越多 6 | * @author Geym 7 | * 8 | */ 9 | public class MultiThreadOOM { 10 | public static class SleepThread implements Runnable{ 11 | public void run(){ 12 | try { 13 | Thread.sleep(10000000); 14 | } catch (InterruptedException e) { 15 | e.printStackTrace(); 16 | } 17 | } 18 | } 19 | public static void main(String args[]){ 20 | for(int i=0;i<1500;i++){ 21 | new Thread(new SleepThread(),"Thread"+i).start(); 22 | System.out.println("Thread"+i+" created"); 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/oom/PermOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.oom; 2 | 3 | 4 | import ch2.perm.CglibBean; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * refs to geym.jvm.ch3.perm 10 | * @author Geym 11 | * 12 | */ 13 | public class PermOOM { 14 | public static void main(String[] args) { 15 | try{ 16 | for(int i=0;i<100000;i++){ 17 | CglibBean bean = new CglibBean("ch3.perm.bean"+i,new HashMap()); 18 | } 19 | }catch(Error e){ 20 | e.printStackTrace(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/oom/SimpleHeapOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.oom; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * -Xmx5m 7 | * @author Geym 8 | * 9 | */ 10 | public class SimpleHeapOOM { 11 | public static void main(String args[]){ 12 | ArrayList list=new ArrayList(); 13 | for(int i=0;i<1024;i++){ 14 | list.add(new byte[1024*1024]); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/program/AveLoadTomcatOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.program; 2 | 3 | /* 4 | import java.io.File; 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | import org.netbeans.lib.profiler.heap.HeapFactory; 10 | import org.netbeans.modules.profiler.oql.engine.api.OQLEngine; 11 | 12 | public class AveLoadTomcatOOM { 13 | public static final String dumpFilePath="d:/tmp/tomcat_oom/tomcat.hprof"; 14 | 15 | public static void main(String args[]) throws Exception{ 16 | OQLEngine engine; 17 | final List creationTimes=new ArrayList(10000); 18 | engine=new OQLEngine(HeapFactory.createHeap(new File(dumpFilePath))); 19 | String query="select s.creationTime from org.apache.catalina.session.StandardSession s"; 20 | engine.executeQuery(query, new OQLEngine.ObjectVisitor(){ 21 | public boolean visit(Object obj){ 22 | creationTimes.add((Long)obj); 23 | return false; 24 | } 25 | }); 26 | 27 | Collections.sort(creationTimes); 28 | 29 | double min=creationTimes.get(0)/1000; 30 | double max=creationTimes.get(creationTimes.size()-1)/1000; 31 | System.out.println("平均压力:"+creationTimes.size()*1.0/(max-min)+"次/秒"); 32 | } 33 | }*/ 34 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/string/ConstantPool.java: -------------------------------------------------------------------------------- 1 | package ch7.string; 2 | 3 | public class ConstantPool { 4 | public static void main(String[] args) { 5 | if(args.length==0)return; 6 | System.out.println(System.identityHashCode((args[0]+Integer.toString(0)))); 7 | System.out.println(System.identityHashCode((args[0]+Integer.toString(0)).intern())); 8 | System.gc(); 9 | System.out.println(System.identityHashCode((args[0]+Integer.toString(0)).intern())); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/string/JDK6StringOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.string; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * JDK6 8 | * -Xmx5m 9 | * @author geym 10 | * 11 | */ 12 | public class JDK6StringOOM { 13 | public static List strList=new ArrayList(); 14 | 15 | public static void main(String args[]){ 16 | for(int i=0;i<10000;i++){ 17 | //模拟读入一个很大的字符串 18 | StringBuffer sb=new StringBuffer(); 19 | for(int j=0;j<10240;j++){ 20 | sb.append(j); 21 | } 22 | //strList.add(new String(sb.toString().substring(0, 1))); 23 | String str=sb.toString().substring(0, 1); 24 | strList.add(str); 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/string/StringBasic.java: -------------------------------------------------------------------------------- 1 | package ch7.string; 2 | 3 | public class StringBasic { 4 | public static void main(String[] args) { 5 | String str1=new String("abc"); 6 | String str2=new String("abc"); 7 | System.out.println(str1==str2); //返回false 8 | System.out.println(str1==str2.intern()); //返回false 9 | System.out.println("abc"==str2.intern()); //返回true 10 | System.out.println(str1.intern()==str2.intern()); //返回true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/string/StringIntern.java: -------------------------------------------------------------------------------- 1 | package ch7.string; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * JDK6 7 | * -XX:MaxPermSize=5m 8 | * ava.lang.OutOfMemoryError: PermGen space 9 | * 10 | * JDK7 11 | * -XX:MaxPermSize=5m -XX:+PrintGC 12 | * 分配在堆 13 | * 14 | * @author geym 15 | * 16 | */ 17 | public class StringIntern { 18 | 19 | public static void main(String[] args) { 20 | ArrayList al=new ArrayList(); 21 | for(int i=0;i<1024*1024*7;i++){ 22 | al.add(String.valueOf(i).intern()); 23 | } 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch7/string/StringInternOOM.java: -------------------------------------------------------------------------------- 1 | package ch7.string; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * -Xmx5m -XX:MaxPermSize=5m 8 | * @author Geym 9 | * 10 | */ 11 | public class StringInternOOM { 12 | public static void main(String[] args) { 13 | List list = new ArrayList(); 14 | int i = 0; 15 | while(true){ 16 | list.add(String.valueOf(i++).intern()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/biased/Biased.java: -------------------------------------------------------------------------------- 1 | package ch8.biased; 2 | 3 | import java.util.List; 4 | import java.util.Vector; 5 | 6 | /** 7 | * @author Geym 8 | * 9 | */ 10 | public class Biased { 11 | public static List numberList =new Vector(); 12 | public static void main(String[] args) throws InterruptedException { 13 | long begin=System.currentTimeMillis(); 14 | int count=0; 15 | int startnum=0; 16 | while(count<10000000){ 17 | numberList.add(startnum); 18 | startnum+=2; 19 | count++; 20 | } 21 | long end=System.currentTimeMillis(); 22 | System.out.println(end-begin); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/biased/ThreadSafe.java: -------------------------------------------------------------------------------- 1 | package ch8.biased; 2 | 3 | import java.util.List; 4 | import java.util.Vector; 5 | 6 | /** 7 | * @author Geym 8 | * 9 | */ 10 | public class ThreadSafe { 11 | public static List numberList =new Vector(); 12 | 13 | 14 | public static class AddToList implements Runnable{ 15 | int startnum=0; 16 | public AddToList(int startnumber){ 17 | startnum=startnumber; 18 | } 19 | @Override 20 | public void run() { 21 | int count=0; 22 | while(count<10000000){ 23 | numberList.add(startnum); 24 | startnum+=2; 25 | count++; 26 | } 27 | } 28 | } 29 | 30 | public static void main(String[] args) throws InterruptedException { 31 | Thread t1=new Thread(new AddToList(0)); 32 | Thread t2=new Thread(new AddToList(1)); 33 | long begin=System.currentTimeMillis(); 34 | t1.start(); 35 | t2.start(); 36 | 37 | while(t1.isAlive() || t2.isAlive()){ 38 | Thread.sleep(1); 39 | } 40 | long end=System.currentTimeMillis(); 41 | System.out.println(end-begin); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/jmm/MultiThreadVolatileLong.java: -------------------------------------------------------------------------------- 1 | package ch8.jmm; 2 | 3 | /** 4 | * @author Administrator 5 | * 6 | */ 7 | public class MultiThreadVolatileLong { 8 | public static volatile long t=0; 9 | public static class ChangeT implements Runnable{ 10 | private long to; 11 | public ChangeT(long to){ 12 | this.to=to; 13 | } 14 | @Override 15 | public void run() { 16 | while(true){ 17 | MultiThreadVolatileLong.t=to; 18 | Thread.yield(); 19 | } 20 | } 21 | } 22 | public static class ReadT implements Runnable{ 23 | @Override 24 | public void run() { 25 | while(true){ 26 | long tmp=MultiThreadVolatileLong.t; 27 | if(tmp!=111L && tmp!=-999L && tmp!=333L && tmp!=-444L) 28 | System.out.println(tmp); 29 | Thread.yield(); 30 | } 31 | } 32 | } 33 | 34 | public static void main(String[] args) { 35 | // System.out.println(Long.toBinaryString(111L)); 36 | // System.out.println(Long.toBinaryString(-999L)); 37 | // System.out.println(Long.toBinaryString(333L)); 38 | // System.out.println(Long.toBinaryString(-444L)); 39 | // System.out.println(Long.toBinaryString(4294966297L)); 40 | // System.out.println(Long.toBinaryString(-4294967185L)); 41 | 42 | new Thread(new ChangeT(111L)).start(); 43 | new Thread(new ChangeT(-999L)).start(); 44 | new Thread(new ChangeT(333L)).start(); 45 | new Thread(new ChangeT(-444L)).start(); 46 | new Thread(new ReadT()).start(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/jmm/VolatileTest.java: -------------------------------------------------------------------------------- 1 | package ch8.jmm; 2 | /** 3 | * -server 4 | * @author Administrator 5 | * 6 | */ 7 | public class VolatileTest { 8 | public static class MyThread extends Thread{ 9 | private boolean stop = false; //确保stop变量在多线程中可见 10 | public synchronized void stopMe(){ //在其他线程中调用,停止本线程 11 | stop=true; 12 | } 13 | public synchronized boolean stopped(){ 14 | return stop; 15 | } 16 | public void run() { 17 | int i = 0; 18 | while (!stopped()) { //在其他线程中改变stop的值 19 | i++; 20 | } 21 | System.out.println("Stop Thread"); 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws InterruptedException { 26 | MyThread t = new MyThread(); 27 | t.start(); 28 | Thread.sleep(1000); 29 | t.stopMe(); 30 | Thread.sleep(1000); 31 | 32 | } 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/lockcoarsenn/LockCoarsen.java: -------------------------------------------------------------------------------- 1 | package ch8.lockcoarsenn; 2 | 3 | public class LockCoarsen { 4 | public static Object lock=new Object(); 5 | public static final int CIRCLE=10000000; 6 | 7 | public static void main(String[] args) { 8 | 9 | 10 | long begintime=System.currentTimeMillis(); 11 | for(int i=0;i numberList =new Vector(); 12 | 13 | 14 | public static class AddToList implements Runnable{ 15 | int startnum=0; 16 | public AddToList(int startnumber){ 17 | startnum=startnumber; 18 | } 19 | @Override 20 | public void run() { 21 | int count=0; 22 | while(count<10000000){ 23 | numberList.add(startnum); 24 | startnum+=2; 25 | count++; 26 | } 27 | } 28 | } 29 | 30 | public static void main(String[] args) throws InterruptedException { 31 | Thread t1=new Thread(new AddToList(0)); 32 | Thread t2=new Thread(new AddToList(1)); 33 | long begin=System.currentTimeMillis(); 34 | t1.start(); 35 | t2.start(); 36 | 37 | while(t1.isAlive() || t2.isAlive()){ 38 | // while(t1.isAlive()){ 39 | Thread.sleep(1); 40 | } 41 | long end=System.currentTimeMillis(); 42 | System.out.println(end-begin); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/threadsafe/ThreadUnSafe.java: -------------------------------------------------------------------------------- 1 | package ch8.threadsafe; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ThreadUnSafe { 7 | public static List numberList =new ArrayList(); 8 | public static class AddToList implements Runnable{ 9 | int startnum=0; 10 | public AddToList(int startnumber){ 11 | startnum=startnumber; 12 | } 13 | @Override 14 | public void run() { 15 | int count=0; 16 | while(count<1000000){ 17 | numberList.add(startnum); 18 | startnum+=2; 19 | count++; 20 | } 21 | } 22 | } 23 | public static void main(String[] args) throws InterruptedException { 24 | Thread t1=new Thread(new AddToList(0)); 25 | Thread t2=new Thread(new AddToList(1)); 26 | t1.start(); 27 | t2.start(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch8/threadsafe/ThreadUnSafeMap.java: -------------------------------------------------------------------------------- 1 | package ch8.threadsafe; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class ThreadUnSafeMap { 7 | public static Map hashMap =new HashMap(); 8 | public static class AddToMap implements Runnable{ 9 | int startnum=0; 10 | public AddToMap(int startnumber){ 11 | startnum=startnumber; 12 | } 13 | @Override 14 | public void run() { 15 | int count=0; 16 | while(count<10000){ 17 | hashMap.put(Integer.toString(startnum),Integer.toBinaryString(startnum)); 18 | startnum+=2; 19 | count++; 20 | } 21 | } 22 | } 23 | public static void main(String[] args) throws InterruptedException { 24 | Thread t1=new Thread(new AddToMap(0)); 25 | Thread t2=new Thread(new AddToMap(1)); 26 | t1.start(); 27 | t2.start(); 28 | while(t1.isAlive() || t2.isAlive()){ 29 | Thread.sleep(1); 30 | } 31 | System.out.println("Add Data Complete!"); 32 | for(int i=0;i<10000;i++){ 33 | System.out.println(hashMap.get(Integer.toString(i))); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch9/FullUser.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | public class FullUser implements Comparable { 4 | public static final int TYPE = 1; 5 | 6 | private int id; 7 | private String name; 8 | 9 | public int getId() { 10 | return id; 11 | } 12 | 13 | public void setId(int id) throws IllegalStateException { 14 | try { 15 | this.id = id; 16 | } catch (IllegalStateException e) { 17 | System.out.println(e.toString()); 18 | } 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | @Override 30 | public int compareTo(Object o) { 31 | Comparable c=this; 32 | c.compareTo(o); 33 | return 0; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch9/SimpleUser.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | public class SimpleUser { 4 | public static final int TYPE = 1; 5 | 6 | private int id; 7 | private String name; 8 | 9 | public int getId() { 10 | return id; 11 | } 12 | 13 | public void setId(int id) throws IllegalStateException { 14 | try { 15 | this.id = id; 16 | } catch (IllegalStateException e) { 17 | System.out.println(e.toString()); 18 | } 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /practicaljvm/src/main/java/ch9/asm/AsmHelloWorld.java: -------------------------------------------------------------------------------- 1 | package ch9.asm; 2 | 3 | import org.objectweb.asm.ClassWriter; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.Opcodes; 6 | 7 | public class AsmHelloWorld extends ClassLoader implements Opcodes { 8 | public static void main(final String args[]) throws Exception { 9 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); 10 | cw.visit(V1_7, ACC_PUBLIC, "Example", null, "java/lang/Object", null); 11 | MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); 12 | mw.visitVarInsn(ALOAD, 0); 13 | mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); 14 | mw.visitInsn(RETURN); 15 | mw.visitMaxs(0, 0); 16 | mw.visitEnd(); 17 | mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); 18 | mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); 19 | mw.visitLdcInsn("Hello World!"); 20 | mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); 21 | mw.visitInsn(RETURN); 22 | mw.visitMaxs(0, 0); 23 | mw.visitEnd(); 24 | byte[] code = cw.toByteArray(); 25 | 26 | AsmHelloWorld loader = new AsmHelloWorld(); 27 | Class exampleClass = loader.defineClass("Example", code, 0, code.length); 28 | exampleClass.getMethods()[0].invoke(null, new Object[] { null }); 29 | 30 | } 31 | } -------------------------------------------------------------------------------- /understandingjvm/README.md: -------------------------------------------------------------------------------- 1 | # 周志明 深入理解JVM源码 -------------------------------------------------------------------------------- /understandingjvm/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jvm-practice 7 | org.lili 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | understandingjvm 14 | 15 | 16 | 17 | cglib 18 | cglib 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | maven-compiler-plugin 27 | 3.5.1 28 | 29 | UTF-8 30 | 1.8 31 | 1.8 32 | true 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch1/Test1.java: -------------------------------------------------------------------------------- 1 | /* 2 | package ch1; 3 | 4 | */ 5 | /* 6 | 7 | public class Test1 { 8 | #语言选项,这个必须设置,否则编译好后会出现一个HashTable的NPE错 9 | export LANG=C 10 | 11 | #Bootstrap JDK的安装路径。必须设置。 12 | export ALT_BOOTDIR=/Library/Java/JavaVirtualMachines/jdk1.7.0_04.jdk/Contents/Home 13 | 14 | #允许自动下载依赖 15 | export ALLOW_DOWNLOADS=true 16 | 17 | #并行编译的线程数,设置为和CPU内核数量一致即可 18 | export HOTSPOT_BUILD_JOBS=6 19 | export ALT_PARALLEL_COMPILE_JOBS=6 20 | 21 | #比较本次build出来的映像与先前版本的差异。这个对我们来说没有意义,必须设置为false,否则sanity检查会报缺少先前版本JDK的映像。如果有设置dev或者DEV_ONLY=true的话这个不显式设置也行。 22 | export SKIP_COMPARE_IMAGES=true 23 | 24 | #使用预编译头文件,不加这个编译会更慢一些 25 | export USE_PRECOMPILED_HEADER=true 26 | 27 | #要编译的内容 28 | export BUILD_LANGTOOLS=true 29 | #export BUILD_JAXP=false 30 | #export BUILD_JAXWS=false 31 | #export BUILD_CORBA=false 32 | export BUILD_HOTSPOT=true 33 | export BUILD_JDK=true 34 | 35 | #要编译的版本 36 | #export SKIP_DEBUG_BUILD=false 37 | #export SKIP_FASTDEBUG_BUILD=true 38 | #export DEBUG_NAME=debug 39 | 40 | #把它设置为false可以避开javaws和浏览器Java插件之类的部分的build。 41 | BUILD_DEPLOY=false 42 | 43 | #把它设置为false就不会build出安装包。因为安装包里有些奇怪的依赖,但即便不build出它也已经能得到完整的JDK映像,所以还是别build它好了。 44 | BUILD_INSTALL=false 45 | 46 | #编译结果所存放的路径 47 | export ALT_OUTPUTDIR=/Users/IcyFenix/Develop/JVM/jdkBuild/openjdk_7u4/build 48 | 49 | #这两个环境变量必须去掉,不然会有很诡异的事情发生(我没有具体查过这些“”诡异的事情”,Makefile脚本检查到有这2个变量就会提示警告“) 50 | unset JAVA_HOME 51 | unset CLASSPATH 52 | 53 | make 2>&1 | tee $ALT_OUTPUTDIR/build.log 54 | 55 | 56 | } 57 | */ 58 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/BADLY_NAMED_CODE.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: BADLY_NAMED_CODE 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-13:12 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class BADLY_NAMED_CODE { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/NameCheckProcessor.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | import javax.annotation.processing.AbstractProcessor; 4 | import javax.annotation.processing.RoundEnvironment; 5 | import javax.annotation.processing.SupportedAnnotationTypes; 6 | import javax.annotation.processing.SupportedSourceVersion; 7 | import javax.lang.model.SourceVersion; 8 | import javax.lang.model.element.TypeElement; 9 | import java.util.Set; 10 | 11 | /** 12 | * @packgeName: ch10 13 | * @ClassName: NameCheckProcessor 14 | * @copyright: CopyLeft 15 | * @description:<描述> 16 | * @author: lili 17 | * @date: 2017/10/13-13:12 18 | * @version: 1.0 19 | * @since: JDK 1.8 20 | */ 21 | @SupportedAnnotationTypes("*") 22 | @SupportedSourceVersion(SourceVersion.RELEASE_8) 23 | public class NameCheckProcessor extends AbstractProcessor{ 24 | 25 | // private NameChecker 26 | 27 | 28 | // @Override 29 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/NameChecker.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: NameChecker 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-13:12 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class NameChecker { 14 | } 15 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example1.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: example1 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-12:41 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class example1 { 14 | 15 | // 方法一带有final修饰 16 | /*public void foo(final int arg) { 17 | final int var = 0; 18 | // do something 19 | } 20 | 21 | // 方法二没有final修饰 22 | public void foo(int arg) { 23 | int var = 0; 24 | // do something 25 | }*/ 26 | 27 | } 28 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example10.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: example10 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-13:01 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class example10 { 14 | /*public static void main(String[] args) { 15 | // 编译器将会提示“Unreachable code” 16 | while (false) { 17 | System.out.println(""); 18 | } 19 | }*/ 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example2.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | 4 | import java.util.*; 5 | 6 | /** 7 | * @packgeName: ch10 8 | * @ClassName: example2 9 | * @copyright: CopyLeft 10 | * @description:<描述> 11 | * @author: lili 12 | * @date: 2017/10/13-12:42 13 | * @version: 1.0 14 | * @since: JDK 1.8 15 | */ 16 | public class example2 { 17 | //注意查看target中的字节码 会自动加入构造方法 18 | public static void main(String[] args) { 19 | Map map = new HashMap(); 20 | map.put("hello", "你好"); 21 | map.put("how are you?", "吃了没?"); 22 | System.out.println(map.get("hello")); 23 | System.out.println(map.get("how are you?")); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example4.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @packgeName: ch10 7 | * @ClassName: example4 8 | * @copyright: CopyLeft 9 | * @description:<描述> 10 | * @author: lili 11 | * @date: 2017/10/13-12:45 12 | * @version: 1.0 13 | * @since: JDK 1.8 14 | */ 15 | public class example4 { 16 | /*public static void method(List list) { 17 | System.out.println("invoke method(List list)"); 18 | }*/ 19 | 20 | public static void method(List list) { 21 | System.out.println("invoke method(List list)"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example5.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: example5 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-12:45 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class example5 { 14 | /*public static String method(List list) { 15 | System.out.println("invoke method(List list)"); 16 | return ""; 17 | } 18 | 19 | public static int method(List list) { 20 | System.out.println("invoke method(List list)"); 21 | return 1; 22 | } 23 | 24 | public static void main(String[] args) { 25 | method(new ArrayList()); 26 | method(new ArrayList()); 27 | }*/ 28 | } 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example6.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * @packgeName: ch10 8 | * @ClassName: example6 9 | * @copyright: CopyLeft 10 | * @description:<描述> 11 | * @author: lili 12 | * @date: 2017/10/13-12:46 13 | * @version: 1.0 14 | * @since: JDK 1.8 15 | */ 16 | public class example6 { 17 | 18 | public static void main(String[] args) { 19 | List list = Arrays.asList(1, 2, 3, 4); 20 | // 如果在JDK 1.7中,还有另外一颗语法糖 , 21 | // 能让上面这句代码进一步简写成List list = [1, 2, 3, 4]; 22 | int sum = 0; 23 | for(int i:list){ 24 | sum += i; 25 | } 26 | System.out.println(sum); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example8.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: example8 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-12:54 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class example8 { 14 | public static void main(String[] args) { 15 | Integer a = 1; 16 | Integer b = 2; 17 | Integer c = 3; 18 | Integer d = 3; 19 | Integer e = 321; 20 | Integer f = 321; 21 | Long g = 3L; 22 | System.out.println(c == d); 23 | System.out.println(e == f); 24 | System.out.println(c == (a + b)); 25 | System.out.println(c.equals(a + b)); 26 | System.out.println(g == (a + b)); 27 | System.out.println(g.equals(a + b)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/example9.java: -------------------------------------------------------------------------------- 1 | package ch10; 2 | 3 | /** 4 | * @packgeName: ch10 5 | * @ClassName: example9 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/13-13:01 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | public class example9 { 14 | public static void main(String[] args) { 15 | if (true) { 16 | System.out.println("block 1"); 17 | } else { 18 | System.out.println("block 2"); 19 | } 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-1.txt: -------------------------------------------------------------------------------- 1 | // 方法一带有final修饰 2 | public void foo(final int arg) { 3 | final int var = 0; 4 | // do something 5 | } 6 | 7 | // 方法二没有final修饰 8 | public void foo(int arg) { 9 | int var = 0; 10 | // do something 11 | } 12 | 13 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-10.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | // 编译器将会提示“Unreachable code” 3 | while (false) { 4 | System.out.println(""); 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-11.txt: -------------------------------------------------------------------------------- 1 | // 可以用"*"表示支持所有Annotations 2 | @SupportedAnnotationTypes("*") 3 | // 只支持JDK 1.6的Java代码 4 | @SupportedSourceVersion(SourceVersion.RELEASE_6) 5 | public class NameCheckProcessor extends AbstractProcessor { 6 | 7 | private NameChecker nameChecker; 8 | 9 | /** 10 | * 初始化名称检查插件 11 | */ 12 | @Override 13 | public void init(ProcessingEnvironment processingEnv) { 14 | super.init(processingEnv); 15 | nameChecker = new NameChecker(processingEnv); 16 | } 17 | 18 | /** 19 | * 对输入的语法树的各个节点进行进行名称检查 20 | */ 21 | @Override 22 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 23 | if (!roundEnv.processingOver()) { 24 | for (Element element : roundEnv.getRootElements()) 25 | nameChecker.checkNames(element); 26 | } 27 | return false; 28 | } 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-13.txt: -------------------------------------------------------------------------------- 1 | public class BADLY_NAMED_CODE { 2 | 3 | enum colors { 4 | red, blue, green; 5 | } 6 | 7 | static final int _FORTY_TWO = 42; 8 | 9 | public static int NOT_A_CONSTANT = _FORTY_TWO; 10 | 11 | protected void BADLY_NAMED_CODE() { 12 | return; 13 | } 14 | 15 | public void NOTcamelCASEmethodNAME() { 16 | return; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-2.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | Map map = new HashMap(); 3 | map.put("hello", "你好"); 4 | map.put("how are you?", "吃了没?"); 5 | System.out.println(map.get("hello")); 6 | System.out.println(map.get("how are you?")); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-3.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | Map map = new HashMap(); 3 | map.put("hello", "你好"); 4 | map.put("how are you?", "吃了没?"); 5 | System.out.println((String) map.get("hello")); 6 | System.out.println((String) map.get("how are you?")); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-4.txt: -------------------------------------------------------------------------------- 1 | public class GenericTypes { 2 | 3 | public static void method(List list) { 4 | System.out.println("invoke method(List list)"); 5 | } 6 | 7 | public static void method(List list) { 8 | System.out.println("invoke method(List list)"); 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-5.txt: -------------------------------------------------------------------------------- 1 | public class GenericTypes { 2 | 3 | public static String method(List list) { 4 | System.out.println("invoke method(List list)"); 5 | return ""; 6 | } 7 | 8 | public static int method(List list) { 9 | System.out.println("invoke method(List list)"); 10 | return 1; 11 | } 12 | 13 | public static void main(String[] args) { 14 | method(new ArrayList()); 15 | method(new ArrayList()); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-6.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | List list = Arrays.asList(1, 2, 3, 4); 3 | // 如果在JDK 1.7中,还有另外一颗语法糖 , 4 | // 能让上面这句代码进一步简写成List list = [1, 2, 3, 4]; 5 | int sum = 0; 6 | for (int i : list) { 7 | sum += i; 8 | } 9 | System.out.println(sum); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-7.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | List list = Arrays.asList( new Integer[] { 3 | Integer.valueOf(1), 4 | Integer.valueOf(2), 5 | Integer.valueOf(3), 6 | Integer.valueOf(4) }); 7 | 8 | int sum = 0; 9 | for (Iterator localIterator = list.iterator(); localIterator.hasNext(); ) { 10 | int i = ((Integer)localIterator.next()).intValue(); 11 | sum += i; 12 | } 13 | System.out.println(sum); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-8.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | Integer a = 1; 3 | Integer b = 2; 4 | Integer c = 3; 5 | Integer d = 3; 6 | Integer e = 321; 7 | Integer f = 321; 8 | Long g = 3L; 9 | System.out.println(c == d); 10 | System.out.println(e == f); 11 | System.out.println(c == (a + b)); 12 | System.out.println(c.equals(a + b)); 13 | System.out.println(g == (a + b)); 14 | System.out.println(g.equals(a + b)); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch10/清单10-9.txt: -------------------------------------------------------------------------------- 1 | public static void main(String[] args) { 2 | if (true) { 3 | System.out.println("block 1"); 4 | } else { 5 | System.out.println("block 2"); 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch11/清单11-2.txt: -------------------------------------------------------------------------------- 1 | public static final int NUM = 15000; 2 | 3 | public static int doubleValue(int i) { 4 | // 这个空循环用于后面演示JIT代码优化过程 5 | for(int j=0; j<100000; j++); 6 | return i * 2; 7 | } 8 | 9 | public static long calcSum() { 10 | long sum = 0; 11 | for (int i = 1; i <= 100; i++) { 12 | sum += doubleValue(i); 13 | } 14 | return sum; 15 | } 16 | 17 | public static void main(String[] args) { 18 | for (int i = 0; i < NUM; i++) { 19 | calcSum(); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch12/Singleton.java: -------------------------------------------------------------------------------- 1 | package ch12; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Singleton { 7 | 8 | private volatile static Singleton instance; 9 | 10 | public static Singleton getInstance() { 11 | if (instance == null) { 12 | synchronized (Singleton.class) { 13 | if (instance == null) { 14 | instance = new Singleton(); 15 | } 16 | } 17 | } 18 | return instance; 19 | } 20 | 21 | public static void main(String[] args) { 22 | Singleton.getInstance(); 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch12/VolatileTest.java: -------------------------------------------------------------------------------- 1 | package ch12; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * volatile变量自增运算测试 8 | * 9 | * @author zzm 10 | */ 11 | public class VolatileTest { 12 | 13 | public static volatile int race = 0; 14 | 15 | public static void increase() { 16 | race++; 17 | } 18 | 19 | private static final int THREADS_COUNT = 20; 20 | 21 | public static void main(String[] args) { 22 | Thread[] threads = new Thread[THREADS_COUNT]; 23 | for (int i = 0; i < THREADS_COUNT; i++) { 24 | threads[i] = new Thread(new Runnable() { 25 | @Override 26 | public void run() { 27 | for (int i = 0; i < 10000; i++) { 28 | increase(); 29 | } 30 | } 31 | }); 32 | threads[i].start(); 33 | } 34 | 35 | // 等待所有累加线程都结束 36 | while (Thread.activeCount() > 1) 37 | Thread.yield(); 38 | 39 | System.out.println(race); 40 | } 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch13/清单13-2.txt: -------------------------------------------------------------------------------- 1 | private static Vector vector = new Vector(); 2 | 3 | public static void main(String[] args) { 4 | while (true) { 5 | for (int i = 0; i < 10; i++) { 6 | vector.add(i); 7 | } 8 | 9 | Thread removeThread = new Thread(new Runnable() { 10 | @Override 11 | public void run() { 12 | for (int i = 0; i < vector.size(); i++) { 13 | vector.remove(i); 14 | } 15 | } 16 | }); 17 | 18 | Thread printThread = new Thread(new Runnable() { 19 | @Override 20 | public void run() { 21 | for (int i = 0; i < vector.size(); i++) { 22 | System.out.println((vector.get(i))); 23 | } 24 | } 25 | }); 26 | 27 | removeThread.start(); 28 | printThread.start(); 29 | 30 | //不要同时产生过多的线程,否则会导致操作系统假死 31 | while (Thread.activeCount() > 20); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch13/清单13-3.txt: -------------------------------------------------------------------------------- 1 | Thread removeThread = new Thread(new Runnable() { 2 | @Override 3 | public void run() { 4 | synchronized (vector) { 5 | for (int i = 0; i < vector.size(); i++) { 6 | vector.remove(i); 7 | } 8 | } 9 | } 10 | }); 11 | 12 | Thread printThread = new Thread(new Runnable() { 13 | @Override 14 | public void run() { 15 | synchronized (vector) { 16 | for (int i = 0; i < vector.size(); i++) { 17 | System.out.println((vector.get(i))); 18 | } 19 | } 20 | } 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch13/清单13-4.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Atomic变量自增运算测试 3 | * 4 | * @author zzm 5 | */ 6 | public class AtomicTest { 7 | 8 | public static AtomicInteger race = new AtomicInteger(0); 9 | 10 | public static void increase() { 11 | race.incrementAndGet(); 12 | } 13 | 14 | private static final int THREADS_COUNT = 20; 15 | 16 | public static void main(String[] args) throws Exception { 17 | Thread[] threads = new Thread[THREADS_COUNT]; 18 | for (int i = 0; i < THREADS_COUNT; i++) { 19 | threads[i] = new Thread(new Runnable() { 20 | @Override 21 | public void run() { 22 | for (int i = 0; i < 10000; i++) { 23 | increase(); 24 | } 25 | } 26 | }); 27 | threads[i].start(); 28 | } 29 | 30 | while (Thread.activeCount() > 1) 31 | Thread.yield(); 32 | 33 | System.out.println(race); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch13/清单13-5.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Atomically increment by one the current value. 3 | * @return the updated value 4 | */ 5 | public final int incrementAndGet() { 6 | for (;;) { 7 | int current = get(); 8 | int next = current + 1; 9 | if (compareAndSet(current, next)) 10 | return next; 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/DirectMemoryOOM.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import sun.misc.Unsafe; 8 | 9 | import java.lang.reflect.Field; 10 | 11 | /** 12 | * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M 13 | * @author zzm 14 | */ 15 | public class DirectMemoryOOM { 16 | 17 | private static final int _1MB = 1024 * 1024; 18 | 19 | public static void main(String[] args) throws Exception { 20 | Field unsafeField = Unsafe.class.getDeclaredFields()[0]; 21 | unsafeField.setAccessible(true); 22 | Unsafe unsafe = (Unsafe) unsafeField.get(null); 23 | while (true) { 24 | unsafe.allocateMemory(_1MB); 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/HeapOOM.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 12 | * @author zzm 13 | */ 14 | public class HeapOOM { 15 | 16 | static class OOMObject { 17 | } 18 | 19 | public static void main(String[] args) { 20 | List list = new ArrayList(); 21 | 22 | while (true) { 23 | list.add(new OOMObject()); 24 | } 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/JavaMethodAreaOOM.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import net.sf.cglib.proxy.Enhancer; 8 | import net.sf.cglib.proxy.MethodInterceptor; 9 | import net.sf.cglib.proxy.MethodProxy; 10 | 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M 15 | * @author zzm 16 | */ 17 | public class JavaMethodAreaOOM { 18 | 19 | public static void main(String[] args) { 20 | while (true) { 21 | Enhancer enhancer = new Enhancer(); 22 | enhancer.setSuperclass(OOMObject.class); 23 | enhancer.setUseCache(false); 24 | enhancer.setCallback(new MethodInterceptor() { 25 | public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 26 | return proxy.invokeSuper(obj, args); 27 | } 28 | }); 29 | enhancer.create(); 30 | } 31 | } 32 | 33 | static class OOMObject { 34 | 35 | } 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/JavaVMStackOOM.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * VM Args:-Xss2M (这时候不妨设大些) 8 | * @author zzm 9 | */ 10 | public class JavaVMStackOOM { 11 | 12 | private void dontStop() { 13 | while (true) { 14 | } 15 | } 16 | 17 | public void stackLeakByThread() { 18 | while (true) { 19 | Thread thread = new Thread(new Runnable() { 20 | 21 | public void run() { 22 | dontStop(); 23 | } 24 | }); 25 | thread.start(); 26 | } 27 | } 28 | 29 | public static void main(String[] args) throws Throwable { 30 | JavaVMStackOOM oom = new JavaVMStackOOM(); 31 | oom.stackLeakByThread(); 32 | } 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/JavaVMStackSOF.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * VM Args:-Xss128k 8 | * @author zzm 9 | */ 10 | public class JavaVMStackSOF { 11 | 12 | private int stackLength = 1; 13 | 14 | public void stackLeak() { 15 | stackLength++; 16 | stackLeak(); 17 | } 18 | 19 | public static void main(String[] args) throws Throwable { 20 | JavaVMStackSOF oom = new JavaVMStackSOF(); 21 | try { 22 | oom.stackLeak(); 23 | } catch (Throwable e) { 24 | System.out.println("stack length:" + oom.stackLength); 25 | throw e; 26 | } 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/RuntimeConstantPoolOOM.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M 12 | * @author zzm 13 | */ 14 | public class RuntimeConstantPoolOOM { 15 | 16 | public static void main(String[] args) { 17 | // 使用List保持着常量池引用,避免Full GC回收常量池行为 18 | List list = new ArrayList(); 19 | // 10MB的PermSize在integer范围内足够产生OOM了 20 | int i = 0; 21 | while (true) { 22 | list.add(String.valueOf(i++).intern()); 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch2/RuntimeConstantPoolOOM2.java: -------------------------------------------------------------------------------- 1 | package ch2; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class RuntimeConstantPoolOOM2 { 7 | 8 | public static void main(String[] args) { 9 | 10 | String str1 = new StringBuilder("中国").append("钓鱼岛").toString(); 11 | System.out.println(str1.intern() == str1); 12 | 13 | String str2 = new StringBuilder("ja").append("va").toString(); 14 | System.out.println(str2.intern() == str2); 15 | } 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/FinalizeEscapeGC.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * 此代码演示了两点: 8 | * 1.对象可以在被GC时自我拯救。 9 | * 2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次 10 | * @author zzm 11 | */ 12 | public class FinalizeEscapeGC { 13 | 14 | public static FinalizeEscapeGC SAVE_HOOK = null; 15 | 16 | public void isAlive() { 17 | System.out.println("yes, i am still alive :)"); 18 | } 19 | 20 | @Override 21 | protected void finalize() throws Throwable { 22 | super.finalize(); 23 | System.out.println("finalize mehtod executed!"); 24 | FinalizeEscapeGC.SAVE_HOOK = this; 25 | } 26 | 27 | public static void main(String[] args) throws Throwable { 28 | SAVE_HOOK = new FinalizeEscapeGC(); 29 | 30 | //对象第一次成功拯救自己 31 | SAVE_HOOK = null; 32 | System.gc(); 33 | // 因为Finalizer方法优先级很低,暂停0.5秒,以等待它 34 | Thread.sleep(500); 35 | if (SAVE_HOOK != null) { 36 | SAVE_HOOK.isAlive(); 37 | } else { 38 | System.out.println("no, i am dead :("); 39 | } 40 | 41 | // 下面这段代码与上面的完全相同,但是这次自救却失败了 42 | SAVE_HOOK = null; 43 | System.gc(); 44 | // 因为Finalizer方法优先级很低,暂停0.5秒,以等待它 45 | Thread.sleep(500); 46 | if (SAVE_HOOK != null) { 47 | SAVE_HOOK.isAlive(); 48 | } else { 49 | System.out.println("no, i am dead :("); 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/ReferenceCountingGC.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * testGC()方法执行后,objA和objB会不会被GC呢? 8 | * @author zzm 9 | */ 10 | public class ReferenceCountingGC { 11 | 12 | public Object instance = null; 13 | 14 | private static final int _1MB = 1024 * 1024; 15 | 16 | /** 17 | * 这个成员属性的唯一意义就是占点内存,以便在能在GC日志中看清楚是否有回收过 18 | */ 19 | private byte[] bigSize = new byte[2 * _1MB]; 20 | 21 | public static void testGC() { 22 | ReferenceCountingGC objA = new ReferenceCountingGC(); 23 | ReferenceCountingGC objB = new ReferenceCountingGC(); 24 | objA.instance = objB; 25 | objB.instance = objA; 26 | 27 | objA = null; 28 | objB = null; 29 | 30 | // 假设在这行发生GC,objA和objB是否能被回收? 31 | System.gc(); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/Test35.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test35 { 7 | private static final int _1MB = 1024 * 1024; 8 | 9 | /** 10 | * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 11 | */ 12 | public static void testAllocation() { 13 | byte[] allocation1, allocation2, allocation3, allocation4; 14 | allocation1 = new byte[2 * _1MB]; 15 | allocation2 = new byte[2 * _1MB]; 16 | allocation3 = new byte[2 * _1MB]; 17 | allocation4 = new byte[4 * _1MB]; // 出现一次Minor GC 18 | } 19 | 20 | public static void main(String[] args) { 21 | //老年代 10M 年轻代 10M 8M eden 1M from 1M to 22 | //allocation1,allocation2,allocation3在eden区分配,但是allocation4在old区分配, 23 | testAllocation(); 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/Test36.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test36 { 7 | private static final int _1MB = 1024 * 1024; 8 | 9 | /** 10 | * VM参数:-XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728 11 | */ 12 | public static void testPretenureSizeThreshold() { 13 | byte[] allocation; 14 | allocation = new byte[4 * _1MB]; //直接分配在老年代中 15 | } 16 | 17 | public static void main(String[] args) { 18 | testPretenureSizeThreshold(); 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/Test37.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test37 { 7 | private static final int _1MB = 1024 * 1024; 8 | 9 | /** 10 | * VM参数:-XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 11 | * -XX:+PrintTenuringDistribution 12 | */ 13 | @SuppressWarnings("unused") 14 | public static void testTenuringThreshold() { 15 | byte[] allocation1, allocation2, allocation3; 16 | allocation1 = new byte[_1MB / 4]; // 什么时候进入老年代决定于XX:MaxTenuringThreshold设置 17 | allocation2 = new byte[4 * _1MB]; 18 | allocation3 = new byte[4 * _1MB]; 19 | allocation3 = null; 20 | allocation3 = new byte[4 * _1MB]; 21 | } 22 | 23 | public static void main(String[] args) { 24 | testTenuringThreshold(); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/Test38.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test38 { 7 | private static final int _1MB = 1024 * 1024; 8 | 9 | /** 10 | * VM参数: -XX:+UseSerialGC -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 11 | * -XX:+PrintTenuringDistribution 12 | */ 13 | @SuppressWarnings("unused") 14 | public static void testTenuringThreshold2() { 15 | byte[] allocation1, allocation2, allocation3, allocation4; 16 | allocation1 = new byte[_1MB / 4]; // allocation1+allocation2大于survivo空间一半 17 | allocation2 = new byte[_1MB / 4]; 18 | allocation3 = new byte[4 * _1MB]; 19 | allocation4 = new byte[4 * _1MB]; 20 | allocation4 = null; 21 | allocation4 = new byte[4 * _1MB]; 22 | } 23 | 24 | public static void main(String[] args) { 25 | testTenuringThreshold2(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch3/Test39.java: -------------------------------------------------------------------------------- 1 | package ch3; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test39 { 7 | private static final int _1MB = 1024 * 1024; 8 | 9 | /** 10 | * VM参数:-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:-HandlePromotionFailure 11 | */ 12 | @SuppressWarnings("unused") 13 | public static void testHandlePromotion() { 14 | byte[] allocation1, allocation2, allocation3, allocation4, allocation5, allocation6, allocation7; 15 | allocation1 = new byte[2 * _1MB]; 16 | allocation2 = new byte[2 * _1MB]; 17 | allocation3 = new byte[2 * _1MB]; 18 | allocation1 = null; 19 | allocation4 = new byte[2 * _1MB]; 20 | allocation5 = new byte[2 * _1MB]; 21 | allocation6 = new byte[2 * _1MB]; 22 | allocation4 = null; 23 | allocation5 = null; 24 | allocation6 = null; 25 | allocation7 = new byte[2 * _1MB]; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/BTraceTest.java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | /** 8 | * Created by lili on 2017/7/16. 9 | */ 10 | public class BTraceTest { 11 | 12 | public int add(int a, int b) { 13 | return a + b; 14 | } 15 | 16 | public static void main(String[] args) throws IOException { 17 | BTraceTest test = new BTraceTest(); 18 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 19 | for (int i = 0; i < 10; i++) { 20 | reader.readLine(); 21 | int a = (int) Math.round(Math.random() * 1000); 22 | int b = (int) Math.round(Math.random() * 1000); 23 | System.out.println(test.add(a, b)); 24 | } 25 | } 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/Bar.java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Bar { 7 | int a = 1; 8 | static int b = 2; 9 | 10 | public int sum(int c) { 11 | return a + b + c; 12 | } 13 | 14 | public static void main(String[] args) { 15 | new Bar().sum(3); 16 | } 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/Test410.java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test410 { 7 | /** 8 | * 线程死锁等待演示 9 | */ 10 | static class SynAddRunalbe implements Runnable { 11 | int a, b; 12 | public SynAddRunalbe(int a, int b) { 13 | this.a = a; 14 | this.b = b; 15 | } 16 | 17 | public void run() { 18 | synchronized (Integer.valueOf(a)) { 19 | synchronized (Integer.valueOf(b)) { 20 | System.out.println(a + b); 21 | } 22 | } 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | for (int i = 0; i < 100; i++) { 28 | new Thread(new SynAddRunalbe(1, 2)).start(); 29 | new Thread(new SynAddRunalbe(2, 1)).start(); 30 | } 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/Test45.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.Map"%> 2 | 3 | 4 | 5 | 服务器线程信息 6 | 7 | 8 |
 9 | <%
10 |     for (Map.Entry stackTrace : Thread.getAllStackTraces().entrySet()) {
11 |         Thread thread = (Thread) stackTrace.getKey();
12 |         StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue();
13 |         if (thread.equals(Thread.currentThread())) {
14 |             continue;
15 |         }
16 |         out.print("\n线程:" + thread.getName() + "\n");
17 |         for (StackTraceElement element : stack) {
18 |             out.print("\t"+element+"\n");
19 |         }
20 |     }
21 | %>
22 | 
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/Test48.java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by lili on 2017/7/16. 8 | */ 9 | public class Test48 { 10 | /** 11 | * 内存占位符对象,一个OOMObject大约占64K 12 | */ 13 | static class OOMObject { 14 | public byte[] placeholder = new byte[64 * 1024]; 15 | } 16 | 17 | public static void fillHeap(int num) throws InterruptedException { 18 | List list = new ArrayList(); 19 | for (int i = 0; i < num; i++) { 20 | // 稍作延时,令监视曲线的变化更加明显 21 | Thread.sleep(50); 22 | list.add(new OOMObject()); 23 | } 24 | System.gc(); 25 | } 26 | 27 | public static void main(String[] args) throws Exception { 28 | fillHeap(1000); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/Test49.java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | 6 | /** 7 | * Created by lili on 2017/7/16. 8 | */ 9 | public class Test49 { 10 | /** 11 | * 线程死循环演示 12 | */ 13 | public static void createBusyThread() { 14 | Thread thread = new Thread(new Runnable() { 15 | public void run() { 16 | while (true) // 第41行 17 | ; 18 | } 19 | }, "testBusyThread"); 20 | thread.start(); 21 | } 22 | 23 | /** 24 | * 线程锁等待演示 25 | */ 26 | public static void createLockThread(final Object lock) { 27 | Thread thread = new Thread(new Runnable() { 28 | public void run() { 29 | synchronized (lock) { 30 | try { 31 | lock.wait(); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | } 37 | }, "testLockThread"); 38 | thread.start(); 39 | } 40 | 41 | public static void main(String[] args) throws Exception { 42 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 43 | br.readLine(); 44 | createBusyThread(); 45 | br.readLine(); 46 | Object obj = new Object(); 47 | createLockThread(obj); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch4/TracingScript .java: -------------------------------------------------------------------------------- 1 | package ch4; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /* BTrace Script Template */ 7 | /* 8 | import com.sun.btrace.annotations.*; 9 | import static com.sun.btrace.BTraceUtils.*; 10 | import static sun.plugin.javascript.navig.JSType.Location; 11 | 12 | @BTrace 13 | public class TracingScript { 14 | @OnMethod( 15 | clazz="org.fenixsoft.monitoring.BTraceTest", 16 | method="add", 17 | location=@Location(Kind.RETURN) 18 | ) 19 | 20 | public static void func(@Self org.fenixsoft.monitoring.BTraceTest instance,int a,int b,@Return int result) { 21 | println("调用堆栈:"); 22 | jstack(); 23 | println(strcat("方法参数A:",str(a))); 24 | println(strcat("方法参数B:",str(b))); 25 | println(strcat("方法结果:",str(result))); 26 | } 27 | } 28 | */ 29 | 30 | 31 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch5/EclipseStartTime_1.0.0.201011281102.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhiliaoo/jvm-practice/10700405970a2fdac620c2ca35cd861d53b71780/understandingjvm/src/main/java/ch5/EclipseStartTime_1.0.0.201011281102.jar -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch6/GetSignature.java: -------------------------------------------------------------------------------- 1 | package ch6; 2 | 3 | import java.lang.reflect.ParameterizedType; 4 | import java.lang.reflect.Type; 5 | import java.util.Arrays; 6 | 7 | /** 8 | * @packgeName: ch6 9 | * @ClassName: GetSignature 10 | * @copyright: CopyLeft 11 | * @description:<描述> 12 | * @author: lili 13 | * @date: 2017/10/14-16:45 14 | * @version: 1.0 15 | * @since: JDK 1.8 16 | */ 17 | public class GetSignature { 18 | public static void main(String[] args) throws ClassNotFoundException { 19 | 20 | Class c = Class.forName("java.lang.String"); 21 | System.out.println(c); 22 | Type[] t = c.getGenericInterfaces(); 23 | System.out.println(t); 24 | for (Type type : t) { 25 | if (type instanceof ParameterizedType) { 26 | // System.out.println("in if"); 27 | Type[] p = ((ParameterizedType) type).getActualTypeArguments(); 28 | System.out.println(Arrays.toString(p)); 29 | // this.clazz = (Class) p[0]; 30 | } 31 | } 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch6/OnlyMe.java: -------------------------------------------------------------------------------- 1 | package ch6; 2 | 3 | /** 4 | * @packgeName: ch6 5 | * @ClassName: OnlyMe 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/14-16:58 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | class Foo{} 14 | 15 | public class OnlyMe { 16 | void onlyme(Foo f){ 17 | synchronized (f){ 18 | System.out.println("do something "); 19 | } 20 | } 21 | 22 | synchronized void onlyme2(){ 23 | System.out.println("do something else"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch6/TestClass.java: -------------------------------------------------------------------------------- 1 | package ch6; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | public class TestClass { 8 | 9 | private int m; 10 | 11 | public int inc() { 12 | return m + 1; 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/ClassLoaderTest.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | 10 | /** 11 | * 类加载器与instanceof关键字演示 12 | * 13 | * @author zzm 14 | */ 15 | public class ClassLoaderTest { 16 | 17 | public static void main(String[] args) throws IOException { 18 | 19 | ClassLoader myLoader = new ClassLoader() { 20 | @Override 21 | public Class loadClass(String name) throws ClassNotFoundException { 22 | try { 23 | String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; 24 | InputStream is = getClass().getResourceAsStream(fileName); 25 | if (is == null) { 26 | return super.loadClass(name); 27 | } 28 | byte[] b = new byte[is.available()]; 29 | is.read(b); 30 | return defineClass(name, b, 0, b.length); 31 | } catch (IOException e) { 32 | throw new ClassNotFoundException(name); 33 | } 34 | } 35 | }; 36 | 37 | Object obj = null; 38 | try { 39 | obj = myLoader.loadClass("org.fenixsoft.classloading.ClassLoaderTest").newInstance(); 40 | } catch (InstantiationException e) { 41 | e.printStackTrace(); 42 | } catch (IllegalAccessException e) { 43 | e.printStackTrace(); 44 | } catch (ClassNotFoundException e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | System.out.println(obj.getClass()); 49 | System.out.println(obj instanceof ClassLoaderTest); 50 | } 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/FieldResolution.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | public class FieldResolution { 8 | 9 | interface Interface0 { 10 | int A = 0; 11 | } 12 | 13 | interface Interface1 extends Interface0 { 14 | int A = 1; 15 | } 16 | 17 | interface Interface2 { 18 | int A = 2; 19 | } 20 | 21 | static class Parent implements Interface1 { 22 | public static int A = 3; 23 | } 24 | 25 | static class Sub extends Parent implements Interface2 { 26 | public static int A = 4; 27 | } 28 | 29 | public static void main(String[] args) { 30 | System.out.println(Sub.A); 31 | } 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/NotInitialization2.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 被动使用类字段演示二: 9 | * 通过数组定义来引用类,不会触发此类的初始化 10 | **/ 11 | public class NotInitialization2 { 12 | 13 | public static void main(String[] args) { 14 | SuperClass[] sca = new SuperClass[10]; 15 | } 16 | 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/NotInitialization3.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 被动使用类字段演示三: 9 | * 常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。 10 | **/ 11 | class ConstClass { 12 | 13 | static { 14 | System.out.println("ConstClass init!"); 15 | } 16 | 17 | public static final String HELLOWORLD = "hello world"; 18 | } 19 | 20 | /** 21 | * 非主动使用类字段演示 22 | **/ 23 | public class NotInitialization3 { 24 | 25 | public static void main(String[] args) { 26 | System.out.println(ConstClass.HELLOWORLD); 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/SuperClass.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 被动使用类字段演示一: 9 | * 通过子类引用父类的静态字段,不会导致子类初始化 10 | **/ 11 | public class SuperClass { 12 | 13 | static { 14 | System.out.println("SuperClass init!"); 15 | } 16 | 17 | public static int value = 123; 18 | } 19 | 20 | class SubClass extends SuperClass { 21 | 22 | static { 23 | System.out.println("SubClass init!"); 24 | } 25 | } 26 | 27 | /** 28 | * 非主动使用类字段演示 29 | **/ 30 | class NotInitialization { 31 | 32 | public static void main(String[] args) { 33 | System.out.println(SubClass.value); 34 | } 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/Test.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test { 7 | static { 8 | i = 0; // 给变量复制可以正常编译通过 9 | //System.out.print(i); // 这句编译器会提示“非法向前引用” 10 | } 11 | static int i = 1; 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/Test76.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test76 { 7 | static class Parent { 8 | public static int A = 1; 9 | static { 10 | A = 2; 11 | } 12 | } 13 | 14 | static class Sub extends Parent { 15 | public static int B = A; 16 | } 17 | 18 | public static void main(String[] args) { 19 | System.out.println(Sub.B); 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch7/Test77.java: -------------------------------------------------------------------------------- 1 | package ch7; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test77 { 7 | static class DeadLoopClass { 8 | static { 9 | // 如果不加上这个if语句,编译器将提示“Initializer does not complete normally”并拒绝编译 10 | if (true) { 11 | System.out.println(Thread.currentThread() + "init DeadLoopClass"); 12 | while (true) { 13 | } 14 | } 15 | } 16 | } 17 | 18 | public static void main(String[] args) { 19 | Runnable script = new Runnable() { 20 | public void run() { 21 | System.out.println(Thread.currentThread() + "start"); 22 | DeadLoopClass dlc = new DeadLoopClass(); 23 | System.out.println(Thread.currentThread() + " run over"); 24 | } 25 | }; 26 | 27 | Thread thread1 = new Thread(script); 28 | Thread thread2 = new Thread(script); 29 | thread1.start(); 30 | thread2.start(); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Dispatch.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 单分派、多分派演示 9 | * 10 | * @author zzm 11 | */ 12 | public class Dispatch { 13 | 14 | static class QQ { 15 | } 16 | 17 | static class _360 { 18 | } 19 | 20 | public static class Father { 21 | public void hardChoice(QQ arg) { 22 | System.out.println("father choose qq"); 23 | } 24 | 25 | public void hardChoice(_360 arg) { 26 | System.out.println("father choose 360"); 27 | } 28 | } 29 | 30 | public static class Son extends Father { 31 | public void hardChoice(QQ arg) { 32 | System.out.println("son choose qq"); 33 | } 34 | 35 | public void hardChoice(_360 arg) { 36 | System.out.println("son choose 360"); 37 | } 38 | } 39 | 40 | public static void main(String[] args) throws InterruptedException { 41 | Father father = new Father(); 42 | Father son = new Son(); 43 | father.hardChoice(new _360()); 44 | son.hardChoice(new QQ()); 45 | } 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/DynamicDispatch.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 方法动态分派演示 9 | * 10 | * @author zzm 11 | */ 12 | public class DynamicDispatch { 13 | 14 | static abstract class Human { 15 | protected abstract void sayHello(); 16 | } 17 | 18 | static class Man extends Human { 19 | @Override 20 | protected void sayHello() { 21 | System.out.println("man say hello"); 22 | } 23 | } 24 | 25 | static class Woman extends Human { 26 | @Override 27 | protected void sayHello() { 28 | System.out.println("woman say hello"); 29 | } 30 | } 31 | 32 | public static void main(String[] args) { 33 | Human man = new Man(); 34 | Human woman = new Woman(); 35 | man.sayHello(); 36 | woman.sayHello(); 37 | man = new Woman(); 38 | man.sayHello(); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/InvokeDynamicTest.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | import java.lang.invoke.*; 7 | 8 | import static java.lang.invoke.MethodHandles.lookup; 9 | 10 | public class InvokeDynamicTest { 11 | 12 | public static void main(String[] args) throws Throwable { 13 | INDY_BootstrapMethod().invokeExact("icyfenix"); 14 | } 15 | 16 | public static void testMethod(String s) { 17 | System.out.println("hello String:" + s); 18 | } 19 | 20 | public static CallSite BootstrapMethod(MethodHandles.Lookup lookup, String name, MethodType mt) throws Throwable { 21 | return new ConstantCallSite(lookup.findStatic(InvokeDynamicTest.class, name, mt)); 22 | } 23 | 24 | private static MethodType MT_BootstrapMethod() { 25 | return MethodType 26 | .fromMethodDescriptorString( 27 | "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", 28 | null); 29 | } 30 | 31 | private static MethodHandle MH_BootstrapMethod() throws Throwable { 32 | return lookup().findStatic(InvokeDynamicTest.class, "BootstrapMethod", MT_BootstrapMethod()); 33 | } 34 | 35 | private static MethodHandle INDY_BootstrapMethod() throws Throwable { 36 | CallSite cs = (CallSite) MH_BootstrapMethod().invokeWithArguments(lookup(), "testMethod", 37 | MethodType.fromMethodDescriptorString("(Ljava/lang/String;)V", null)); 38 | return cs.dynamicInvoker(); 39 | } 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/MethodHandleTest.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.lang.invoke.MethodHandle; 8 | import java.lang.invoke.MethodType; 9 | 10 | import static java.lang.invoke.MethodHandles.lookup; 11 | 12 | /** 13 | * JSR 292 MethodHandle基础用法演示 14 | * 15 | * @author zzm 16 | */ 17 | public class MethodHandleTest { 18 | 19 | static class ClassA { 20 | public void println(String s) { 21 | System.out.println(s); 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws Throwable { 26 | Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); 27 | // 无论obj最终是哪个实现类,下面这句都能正确调用到println方法。 28 | getPrintlnMH(obj).invokeExact("icyfenix"); 29 | 30 | 31 | // ClassA a = new ClassA(); 32 | // a.println("2"); 33 | } 34 | 35 | private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable { 36 | // MethodType:代表“方法类型”,包含了方法的返回值(methodType()的第一个参数) 37 | // 和具体参数(methodType()第二个及以后的参数)。 38 | MethodType mt = MethodType.methodType(void.class, String.class); 39 | // lookup()方法来自于MethodHandles.lookup,这句的作用是在指定类中查找符合给定的 40 | // 方法名称、方法类型,并且符合调用权限的方法句柄。 41 | // 因为这里调用的是一个虚方法,按照Java语言的规则,方法第一个参数是隐式的,代表该方 42 | // 法的接收者,也即是this指向的对象,这个参数以前是放在参数列表中进行传递,现在提供了 43 | // bindTo()方法来完成这件事情。 44 | return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); 45 | } 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Overload.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | public class Overload { 8 | 9 | // public static void sayHello(Object arg) { 10 | // System.out.println("hello Object"); 11 | // } 12 | 13 | // public static void sayHello(int arg) { 14 | // System.out.println("hello int"); 15 | // } 16 | 17 | // public static void sayHello(long arg) { 18 | // System.out.println("hello long"); 19 | // } 20 | 21 | // public static void sayHello(Character arg) { 22 | // System.out.println("hello Character"); 23 | // } 24 | 25 | // public static void sayHello(char arg) { 26 | // System.out.println("hello char"); 27 | // } 28 | 29 | public static void sayHello(char... arg) { 30 | System.out.println("hello char ..."); 31 | } 32 | 33 | // public static void sayHello(Serializable arg) { 34 | // System.out.println("hello Serializable"); 35 | // } 36 | 37 | public static void main(String[] args) { 38 | sayHello('a'); 39 | } 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/SonTest.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * @packgeName: ch8 5 | * @ClassName: SonTest 6 | * @copyright: CopyLeft 7 | * @description:<描述> 8 | * @author: lili 9 | * @date: 2017/10/14-12:31 10 | * @version: 1.0 11 | * @since: JDK 1.8 12 | */ 13 | class GrandFather{ 14 | void thinking(){ 15 | System.out.println("I am a grandfather"); 16 | } 17 | } 18 | 19 | class Father extends GrandFather{ 20 | void thinking(){ 21 | System.out.println("I am a father"); 22 | } 23 | } 24 | 25 | class Son extends Father{ 26 | void thinking(){ 27 | GrandFather father = new GrandFather(); 28 | father.thinking(); 29 | } 30 | } 31 | 32 | 33 | public class SonTest { 34 | public static void main(String[] args) { 35 | Son s = new Son(); 36 | s.thinking(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/StaticDispatch.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | /** 8 | * 方法静态分派演示 9 | * @author zzm 10 | */ 11 | public class StaticDispatch { 12 | 13 | static abstract class Human { 14 | } 15 | 16 | static class Man extends Human { 17 | } 18 | 19 | static class Woman extends Human { 20 | } 21 | 22 | public void sayHello(Human guy) { 23 | System.out.println("hello,guy!"); 24 | } 25 | 26 | public void sayHello(Man guy) { 27 | System.out.println("hello,gentleman!"); 28 | } 29 | 30 | public void sayHello(Woman guy) { 31 | System.out.println("hello,lady!"); 32 | } 33 | 34 | public static void main(String[] args) { 35 | Human man = new Man(); 36 | Human woman = new Woman(); 37 | StaticDispatch sr = new StaticDispatch(); 38 | sr.sayHello(man); 39 | sr.sayHello(woman); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/StaticResolution.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * 方法静态解析演示 8 | * 9 | * @author zzm 10 | */ 11 | public class StaticResolution { 12 | 13 | public static void sayHello() { 14 | System.out.println("hello world"); 15 | } 16 | 17 | public static void main(String[] args) { 18 | StaticResolution.sayHello(); 19 | } 20 | 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Test81.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test81 { 7 | public static void main(String[] args) { 8 | byte[] placeholder = new byte[64 * 1024 * 1024]; 9 | System.gc(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Test82.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test82 { 7 | public static void main(String[] args){ 8 | { 9 | byte[] placeholder = new byte[64 * 1024 * 1024]; 10 | } 11 | System.gc(); 12 | } 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Test83.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test83 { 7 | public static void main(String[] args){ 8 | { 9 | byte[] placeholder = new byte[64 * 1024 * 1024]; 10 | } 11 | int a = 0; 12 | System.gc(); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch8/Test84.java: -------------------------------------------------------------------------------- 1 | package ch8; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | public class Test84 { 7 | public static void main(String[] args) { 8 | int a; 9 | // System.out.println(a); 10 | } 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/98.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="ch9.JavaClassExecuter" %> 2 | <%@ page import="java.io.FileInputStream" %> 3 | <%@ page import="java.io.InputStream" %> 4 | <% 5 | InputStream is = new FileInputStream("c:/TestClass.class"); 6 | byte[] b = new byte[is.available()]; 7 | is.read(b); 8 | is.close(); 9 | 10 | out.println(""); 13 | %> 14 | 15 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/ByteUtils.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * Bytes数组处理工具 8 | * @author 9 | */ 10 | public class ByteUtils { 11 | 12 | public static int bytes2Int(byte[] b, int start, int len) { 13 | int sum = 0; 14 | int end = start + len; 15 | for (int i = start; i < end; i++) { 16 | int n = ((int) b[i]) & 0xff; 17 | n <<= (--len) * 8; 18 | sum = n + sum; 19 | } 20 | return sum; 21 | } 22 | 23 | public static byte[] int2Bytes(int value, int len) { 24 | byte[] b = new byte[len]; 25 | for (int i = 0; i < len; i++) { 26 | b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff); 27 | } 28 | return b; 29 | } 30 | 31 | public static String bytes2String(byte[] b, int start, int len) { 32 | return new String(b, start, len); 33 | } 34 | 35 | public static byte[] string2Bytes(String str) { 36 | return str.getBytes(); 37 | } 38 | 39 | public static byte[] bytesReplace(byte[] originalBytes, int offset, int len, byte[] replaceBytes) { 40 | byte[] newBytes = new byte[originalBytes.length + (replaceBytes.length - len)]; 41 | System.arraycopy(originalBytes, 0, newBytes, 0, offset); 42 | System.arraycopy(replaceBytes, 0, newBytes, offset, replaceBytes.length); 43 | System.arraycopy(originalBytes, offset + len, newBytes, offset + replaceBytes.length, originalBytes.length - offset - len); 44 | return newBytes; 45 | } 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/DynamicProxyTest.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Proxy; 6 | 7 | /** 8 | * Created by lili on 2017/7/16. 9 | */ 10 | public class DynamicProxyTest { 11 | 12 | interface IHello { 13 | void sayHello(); 14 | } 15 | 16 | static class Hello implements IHello { 17 | @Override 18 | public void sayHello() { 19 | try { 20 | Thread.sleep(3000); 21 | } catch (InterruptedException e) { 22 | e.printStackTrace(); 23 | } 24 | System.out.println("hello world"); 25 | } 26 | } 27 | 28 | static class DynamicProxy implements InvocationHandler { 29 | 30 | Object originalObj; 31 | 32 | Object bind(Object originalObj) { 33 | this.originalObj = originalObj; 34 | return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(), originalObj.getClass().getInterfaces(), this); 35 | } 36 | 37 | @Override 38 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 39 | long timeStart = System.currentTimeMillis(); 40 | method.invoke(originalObj, args); 41 | System.out.println("方法执行耗费时间:"+(System.currentTimeMillis()-timeStart)); 42 | return null; 43 | } 44 | } 45 | 46 | public static void main(String[] args) { 47 | 48 | System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles",true); 49 | IHello hello = (IHello) new DynamicProxy().bind(new Hello()); 50 | hello.sayHello(); 51 | } 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/HackSystem.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.InputStream; 9 | import java.io.PrintStream; 10 | 11 | /** 12 | * 为JavaClass劫持java.lang.System提供支持 13 | * 除了out和err外,其余的都直接转发给System处理 14 | * 15 | * @author zzm 16 | */ 17 | public class HackSystem { 18 | 19 | public final static InputStream in = System.in; 20 | 21 | private static ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 22 | 23 | public final static PrintStream out = new PrintStream(buffer); 24 | 25 | public final static PrintStream err = out; 26 | 27 | public static String getBufferString() { 28 | return buffer.toString(); 29 | } 30 | 31 | public static void clearBuffer() { 32 | buffer.reset(); 33 | } 34 | 35 | public static void setSecurityManager(final SecurityManager s) { 36 | System.setSecurityManager(s); 37 | } 38 | 39 | public static SecurityManager getSecurityManager() { 40 | return System.getSecurityManager(); 41 | } 42 | 43 | public static long currentTimeMillis() { 44 | return System.currentTimeMillis(); 45 | } 46 | 47 | public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) { 48 | System.arraycopy(src, srcPos, dest, destPos, length); 49 | } 50 | 51 | public static int identityHashCode(Object x) { 52 | return System.identityHashCode(x); 53 | } 54 | 55 | // 下面所有的方法都与java.lang.System的名称一样 56 | // 实现都是字节转调System的对应方法 57 | // 因版面原因,省略了其他方法 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/HotSwapClassLoader.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | /** 7 | * 为了多次载入执行类而加入的加载器
8 | * 把defineClass方法开放出来,只有外部显式调用的时候才会使用到loadByte方法 9 | * 由虚拟机调用时,仍然按照原有的双亲委派规则使用loadClass方法进行类加载 10 | * 11 | * @author zzm 12 | */ 13 | public class HotSwapClassLoader extends ClassLoader { 14 | 15 | public HotSwapClassLoader() { 16 | super(HotSwapClassLoader.class.getClassLoader()); 17 | } 18 | 19 | public Class loadByte(byte[] classByte) { 20 | return defineClass(null, classByte, 0, classByte.length); 21 | } 22 | 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /understandingjvm/src/main/java/ch9/JavaClassExecuter.java: -------------------------------------------------------------------------------- 1 | package ch9; 2 | 3 | /** 4 | * Created by lili on 2017/7/16. 5 | */ 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * JavaClass执行工具 11 | * 12 | * @author zzm 13 | */ 14 | public class JavaClassExecuter { 15 | 16 | /** 17 | * 执行外部传过来的代表一个Java类的Byte数组
18 | * 将输入类的byte数组中代表java.lang.System的CONSTANT_Utf8_info常量修改为劫持后的HackSystem类 19 | * 执行方法为该类的static main(String[] args)方法,输出结果为该类向System.out/err输出的信息 20 | * 21 | * @param classByte 代表一个Java类的Byte数组 22 | * @return 执行结果 23 | */ 24 | public static String execute(byte[] classByte) { 25 | HackSystem.clearBuffer(); 26 | ClassModifier cm = new ClassModifier(classByte); 27 | byte[] modiBytes = cm.modifyUTF8Constant("java/lang/System", "org/fenixsoft/classloading/execute/HackSystem"); 28 | HotSwapClassLoader loader = new HotSwapClassLoader(); 29 | Class clazz = loader.loadByte(modiBytes); 30 | try { 31 | Method method = clazz.getMethod("main", new Class[]{String[].class}); 32 | method.invoke(null, new String[]{null}); 33 | } catch (Throwable e) { 34 | e.printStackTrace(HackSystem.out); 35 | } 36 | return HackSystem.getBufferString(); 37 | } 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /up.push.git.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | git add -A && git commit -m "up" && git push -------------------------------------------------------------------------------- /wikipedia/README.md: -------------------------------------------------------------------------------- 1 | https://www.artima.com/insidejvm/resources/index.html 2 | 3 | https://github.com/deephacks/awesome-jvm 4 | 5 | tools: https://www.eclipse.org/mat/ 6 | 7 | Oracle官方工具类:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/index.html 8 | 9 | Site: 10 | http://www.javaperformancetuning.com/ 11 | http://java-performance.info/ 12 | 13 | Cache Coherence Protocols Analyzer 14 | https://kshitizdange.github.io/418CacheSim/final-report 15 | 16 | https://en.wikipedia.org/wiki/Cache_coherence 17 | 18 | GC:https://github.com/chewiebug/GCViewer 19 | 20 | ClassFile: https://github.com/ingokegel/jclasslib 21 | 22 | 1 对象内存分配在编译时还是运行时? 23 | 24 | 2 对象内存分配策略是什么? 25 | 26 | YGC问题排查过程:https://blog.csdn.net/ljw36060421/article/details/107308673?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-6.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-6.nonecase&request_id=5f1fec4f9cc79f6252ce3616 27 | 28 | # Notes 29 | 30 | Core java doc:https://docs.oracle.com/en/java/javase/14/books.html 31 | 32 | https://openjdk.java.net/groups/hotspot/ 33 | 34 | https://wiki.openjdk.java.net/display/HotSpot/Presentations 35 | 36 | https://en.wikipedia.org/wiki/HotSpot 37 | 38 | https://openjdk.java.net/projects/mlvm/ (userful slide) 39 | 40 | Jeremy Singer:http://www.dcs.gla.ac.uk/~jsinger/pdfs/ 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /wikipedia/REVIEW.md: -------------------------------------------------------------------------------- 1 | # 复习 2 | 3 | - 聊聊JVM? 4 | - 静态角度:三大部分和内存模型,编译,执行引擎,内存管理,内存模型。 5 | - 动态角度:Javac**前端编译**Java文件成class文件,**执行引擎**中的类加载器将class加载到内存中,形成**内存区域**,执行程序指令,执行指令需要遵循**内存模型**,然后内存被**创建**和**回收**,执行后期,会有**后端编译**器将其编译成机器码。 6 | - 运行时数据结构是什么? 7 | - 虚拟机对象创建,内存布局,访问定位是什么? 8 | - OOM案例有哪些? 9 | - 内存分配策略是什么? 10 | - 内存回收策略是什么? 11 | - 如何判断对象需要回收? 12 | - 垃圾回收算法有哪些? 13 | - 垃圾回收器有哪些? 14 | - 类文件结构是什么样的? 15 | - 常见字节码指令有哪些?*invokevirtual* ,*invokevirtual*作用是什么? 16 | - 聊聊类加载? 17 | - 什么时候会触发类加载? 18 | - 类加载过程是什么? 19 | - 类加载模型是什么? 20 | - 有哪些类加载的案例? 21 | - 聊聊字节码执行引擎? 22 | - Java中方法调用实现原理是什么? 23 | - 运行时候的栈帧结构是什么? 24 | - 类加载案例有哪些? 25 | - 聊聊程序编译? 26 | - 前端编译和后端编译区别是什么? 27 | - JIT是什么? 28 | - 编译器优化技术有哪些? 29 | - 聊聊Java内存模型? 30 | - Java线程实现原理是什么? 31 | - 锁优化过程是什么样的? 32 | --------------------------------------------------------------------------------