以下文章来自java开发那些事儿,作者又贪又懒1.JVM是如何创建对象的?首先检查class文件是否加载;然后选择内存分配方式;分配内存的过程使用CAS和TLAB来处理并发问题;最后执行init方法来初始化零值。2、JVM在创建对象时是如何分配内存的?根据内存是否规律来决定采用何种分配方式。内存正则化使用指针冲突,内存不规则化使用空闲列表。堆内存是否规则取决于使用的垃圾回收方法是否会产生内存碎片,如果会产生内存碎片是否会进行碎片整理。3、知道指针碰撞和freelist分别是怎么分配内存的吗?指针冲突是指JVM会维护一个指针。指针的一侧是已用内存,另一侧是未使用内存。为对象分配内存时,指针会移动到未使用内存的末尾,直到内存刚好到达对象所需的内存。size_java-训练。freelist是指JVM会维护一个列表,记录哪些内存是可用的。当为一个对象分配内存时,它会在这个链表中找到足够大的内存分配给该对象。4.你知道哪些内存分配策略?优先分配在Eden区;大对象直接进入老年代,例如非常长的字符串或具有许多元素的数组。可以使用-XX:PertenureSizeThreshold参数指定所需内存大于该值的对象直接进入老年代,但该参数只对parNew收集器和串行收集器有效;long-lived对象可以通过-XX:MaxTenuringThreshold参数指定年龄大于该值的对象进入老年代。该参数默认值为15;动态年龄判断,即年龄没有达到-XX:MaxTenuringThreshold指定的值,但是年龄为x的所有对象占用的内存总和大于from区和to区总内存的一半,则年龄大于x的对象将进入老年代。5、你了解内存分配的保证机制吗?在进行YGC之前,JVM会检查老年代中的最大连续可用空间是否大于新生代中所有对象占用内存的总和。如果较大,则可以保证YGC是安全的;如果不大于,则看-XX:HandlePromotionFailure参数是否允许YGC失败,如果不允许,则进行fullGC;如果允许,则判断老年代的大小是否大于每次提升到老年代的对象的平均大小,如果不是,那么也会进行一次fullGC,如果是,那么YGC是可能的。6、创建对象后,如何定位对象?有两种方式,直接指针和句柄寻址:句柄寻址是指堆中有一个实例池和一个句柄池,实例池存储实例数据,句柄池存储两个指针,一个指向实例池,一个指向实例池。一个指向方法区。优点是如果对象被移动,存储在栈中的引用不需要改变,只需改变句柄池中指向实例池的指针即可指针定位,就是我们常用的sunjdk和openjdk的hotspotJVM使用的方法。7.对象引用有多少种类型?对象有四种类型的引用,强引用、弱引用、弱引用和虚引用:强引用是最常用的。当内存不足时,JVM宁愿OOM也不愿垃圾回收;软引用是指当内存不足时,GC会对其进行回收;弱引用是指无论内存是否足够,只要被GC找到,就会被回收;幻象引用与无引用一样,不决定对象的生命周期,可用于跟踪GC情况;软引用和弱引用可以和ReferenceQueue一起使用,回收后会加入到这个队列中;虚引用必须和ReferenceQueue一起使用,否则没有意义。8、你了解JVM参数调优吗?JVM调优主要是对堆内存进行调优。它有很多参数可以设置。常用参数有:-Xms:堆内存的初始大小,默认值为物理内存的1/64;-Xmx:堆内存的最大大小值,默认为物理内存的1/4;-Xmn:新建区域的大小,默认占堆内存的1/3;-XX:MaxTenuringThreshold:对象提升到老年代的年龄阈值,默认15;-XX:+PrintGCDetails:打印GC详细信息。9.你用过哪些JVM调优工具?在jdk/bin目录下,有两个工具,jconsole和jvisualvm:jconsole可以监控JVM中的线程、内存和类;jvisualvm是一个比较通用的分析工具,可以分析内存快照,线程快照,以及程序死锁和GC情况等。
