微软的网站开发软件,建设一个网站app需要多少钱,如何修改网站主页,介休网站建设1. JVM内存与本地内存 JVM内存#xff1a;受虚拟机内存大小的参数控制#xff0c;当大小超过参数设置的大小时会报OOM。本地内存#xff1a;本地内存不受虚拟机内存参数的限制#xff0c;只受物理内存容量的限制#xff1b;虽然不受参数的限制#xff0c;如果所占内存超过…1. JVM内存与本地内存 JVM内存受虚拟机内存大小的参数控制当大小超过参数设置的大小时会报OOM。本地内存本地内存不受虚拟机内存参数的限制只受物理内存容量的限制虽然不受参数的限制如果所占内存超过物理内存仍然会报OOM。 2. JVM内存结构 虚拟机栈服务于Java方法本地方法栈服务于本地方法程序计数器保存当前线程执行的字节码位置当然每个线程工作时都有独立的计数器。堆用于存放对象方法区用于存放常量、静态变量、数据类型、类信息等元数据 3. 线程独占与共享区域 独占虚拟机栈、本地方法栈、程序计数器共享堆、方法区 4. 栈与堆的区别 栈是运行时单位代表逻辑且区域连续堆是存储单位代表数据区域不连续 5. 方法区、永久代、元空间 方法区是规范是概念。永久代是实现在JDK7及之前版本是方法区的一种实现。元空间是实现在JDK8及之后版本是方法区的一种实现。替代了永久代 6. 元空间为什么替代了永久代 突破内存限制减少OOM。 由于元空间使用的是本地内存而不是 JVM 内存。提高 Full GC 的效率。 因为永久代中存放了很多 JVM 需要的类信息这些数据大多数是不会被清理的所以 Full GC 往往无法回收多少空间。但在元空间模型中由于字符串常量池已移至堆中因此可以更有效地进行垃圾回收避免了因频繁的 Full GC 导致的性能影响。满足不同的类加载需求和动态类加载的情况。 元空间可以动态地调整大小在一些大型的、模块化的应用中可能需要加载大量的类这就需要大量的元数据存储空间。避免永久代调优和大小设置的复杂性。 在 Java8 之前的版本中通常需要手动设置永久代的大小以避免内存溢出的错误。这增加了应用的配置和管理的复杂性。而元空间使用本地内存根据实际需求动态调整大大简化了内存管理的复杂性。 7. JVM内存可见性 线程对于变量的操作只能在自己的工作内存中进行而不能直接对主存操作。 8. 类的生命周期 加载通过类的完全限定名查找此类字节码文件并创建Class对象。验证确保Class文件符合当前虚拟机的要求。准备为static修饰的类变量分配内存不包含final修饰的变量因为final已经在编译时分配。解析将常量池的符号引用替换为直接引用。初始化静态块执行、静态变量赋值。使用new出对象程序中使用。卸载执行垃圾回收。 9. 符号引用和直接引用 符号引用即用**(用字符串符号的形式)**来表示引用其实被引用的类、方法或者变量还没有被加载到内存中。而直接引用则是有具体引用地址的指针被引用的类、方法或者变量已经被加载到内存中。 10. 类的初始化 只有对类主动使用时才会初始化触发条件包括 创建类的实例时。访问类的静态方法或静态变量的时候。使用Class.forName反射类的时候。某个子类初始化的时候。 11. 双亲委派加载机制 AppClassLoader从缓存查找类没有则委托给父加载器ExtClassLoaderExtClassLoader从缓存查找类没有则委托给父加载器BootStrapClassLoaderBootStrapClassLoader从缓存查找类没有则sun.mic.boot.class路径查找BootStrapClassLoader从sun.mic.boot.class路径查找没有则让子类ExtClassLoader加载ExtClassLoader从java.ext.dirs路径查找没有则让子类AppClassLoader加载AppClassLoader从java.class.path路径查找如果找到就加载类否则就抛出异常。 12. 双亲委派机制的优点 避免类的重复加载避免Java的核心API被篡改 13. GC如何判断对象可以被回收 引用计数法每个对象有一个引用计数属性新增一个引用时计数加1引用释放时计数减1计数为0时可以回收可达性分析法从GC Roots开始向下搜索搜索所走过的路径称为引用链当一个对象到GC Roots没有任何引用链相连时则证明此对象是不可用的那么虚拟机就判断是可回收对象 14. 可达性分析算法 可达性算法中的不可达对象并不是立即死亡的对象拥有一次自我拯救的机会当对象编程GC Roots不可达时GC会判断该对象是否执行过finalize方法若执行了则直接回收。否则若对象未执行过finalized方法将其放入F-Queue队列。执行finalize方法完毕后GC会再次判断该对象是否可达若不可达则进行回收否则对象复活。 15. 四种JVM的垃圾回收算法 标记-清除算法标记无用对象然后进行清除回收。缺点效率不高无法清除垃圾碎片。 标记-整理算法标记无用对象让所有存活的对象都向一端移动然后直接清除掉端边界以外的内存。 复制算法按照容量划分二个大小相等的内存区域当一块用完的时候将活着的对象复制到另一块上然后再把已使用的内存空间一次清理掉。缺点内存使用率不高只有原来的一半。 分代算法根据对象存活周期的不同将内存划分为几块一般是新生代和老年代新生代基本采用复制算法老年代采用标记整理算法。 16. 分代算法 new新对象放入堆中如果在Eden区没有空间那就发生Minor GC保留存活的对象当新生代仍然没有空间那就将部分年龄大的新生代对象放入老年代当老年代仍然没有空间那就发生Major GC保留存活的对象Major GC之后仍然没有空间就会抛出OOM 17. 为什么会出现OOM 内存泄漏申请使用完的内存没有释放导致虚拟机不能再次使用该内存此时这段内存就泄露了。因为申请者不用了而又不能被虚拟机分配给别人用内存溢出申请的内存超出了 JVM 能提供的内存大小此时称之为溢出内存泄漏持续存在最后一定会溢出两者是因果关系 18. 常见的OOM报错 方法区溢出 报错信息java.lang.OutOfMemoryError: PermGen space常见问题一般出现于大量Class对象或者方法区过小 栈区溢出 报错信息java.lang.StackOverflowError常见问题一般是由于程序中存在 死循环或者深度递归调用 造成的或者栈区过小 堆区溢出 报错信息java.lang.OutOfMemoryError: Java heap space常见问题内存泄漏、内存溢出 19. OOM如何解决 主要使用dump文件和jprofiler两个工具具体自行学习 20. JVM的元空间中会发生垃圾回收吗 垃圾回收不会发生在元空间如果元空间满了或者是超过了临界值会触发完全垃圾回收(FullGC)。如果正确设置元空间大小那么就可以避免Full GC 21. 查看相关线程命令 jps(JVM Process Status Tool)显示指定系统内所有的HotSpot虚拟机进程。jstat(JVM statistics Monitoring)显示出类装载、内存、垃圾收集、JIT编译等运行数据。jmap(JVM Memory Map)命令用于生成heap dump文件jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用用来分析jmap生成的dumpjhat内 置了一个微型的HTTP/HTML服务器生成dump的分析结果后可以在浏览器中查看jstack用于生成java虚拟机当前时刻的线程快照。jinfo(JVM Configuration info)这个命令作用是实时查看和调整虚拟机运行参数。 22. Minor GC与Full GC分别在什么时候发生 新生代内存不够用时候发生MGC也叫YGCJVM内存不够的时候发生FGC。 23. 对象一定分配在堆中吗有没有了解逃逸分析技术 不一定的JVM通过「逃逸分析」那些逃不出方法的对象会在栈上分配。 24. 什么是逃逸分析 方法逃逸在一个方法体内定义一个局部变量而它可能被外部方法引用比如作为调用参数传递给方法或作为对象直接返回。或者可以理解成对象跳出了方法。线程逃逸这个对象被其他线程访问到比如赋值给了实例变量并被其他线程访问到了。对象逃出了当前线程。逃逸分析没有发生逃逸的对象会进一步优化将其放在栈中 // sb就逃逸了
public static StringBuffer craeteStringBuffer(String s1, String s2) {StringBuffer sb new StringBuffer();sb.append(s1);sb.append(s2);return sb;
}// sb没有逃逸了
public static String createStringBuffer(String s1, String s2) {StringBuffer sb new StringBuffer();sb.append(s1);sb.append(s2);return sb.toString();
}25. 逃逸分析带来的好处 同步省略如果对象只能一个线程被访问到那么对于这个对象的操作可以不考虑同步。将堆分配转化为栈分配对象可能是栈分配的候选而不是堆分配。分离对象有的对象可以那么对象的部分或全部可以不存储在内存而是存储在CPU寄存器中。 26. 逃逸分析的开启关闭 从jdk 1.7开始已经默认开始逃逸分析如需关闭需要指定-XX:-DoEscapeAnalysis-XX:DoEscapeAnalysis 表示开启逃逸分析-XX:-DoEscapeAnalysis 表示关闭逃逸分析 27. 同步省略 在动态编译同步块的时候JIT编译器可以借助逃逸分析来证实同步块的对象只能够被一个线程访问就会取消对这部分代码的同步这个过程也叫锁消除。
如以下代码
public void f() {Object hollis new Object();synchronized(hollis) {System.out.println(hollis);}
}hollis对象的生命周期只在f()方法中并不会被其他线程所访问到所以在JIT编译阶段优化成
public void f() {Object hollis new Object();System.out.println(hollis);
}28. 元空间为什么能替代永久代 区别永久代存在于JVM限制内存元空间存在于本地内存。所以元空间会更大。好处能够避免方法区OOM异常虽然我们可以通过设置永久代的大小来解决OOM但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。当使用元空间时可以加载多少类的元数据就由系统的实际可用空间来控制啦即元空间具有伸缩性。 29. Stop The World 进行垃圾回收的过程中会涉及对象的移动。为了保证对象引用更新的正确性必须暂停所有的用户线程像这样的停顿虚拟机设计者形象描述为「Stop The World」也简称STW。 30. 指针碰撞 分配方式一般情况下JVM的对象都放在堆内存中发生逃逸分析除外。当类加载检查通过后Java虚拟机开始为新生对象分配内存。如果Java堆中内存是绝对规整的所有被使用过的的内存都被放到一边空闲的内存放到另外一边中间放着一个指针作为分界点的指示器所分配内存仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的实例。指针碰撞如果现在两个线程同时创建对象呢 31. 空闲列表 如果Java堆内存中的内存并不是规整的已被使用的内存和空闲的内存相互交错在一起不可以进行指针碰撞啦虚拟机必须维护一个列表记录哪些内存是可用的在分配的时候从列表找到一块大的空间分配给对象实例并更新列表上的记录这种分配方式就是空闲列表。 32. 什么是TLAB 每个线程都有自己的一小块内存这就是TLABThread Local Allocation Buffer本地线程分配缓存 。虚拟机通过 -XX:UseTLAB 设定它的。 33. JVM有哪些垃圾回收器 Serial新生代、单线程、复制算法适用于小堆、单核ParScavenge新生代、多线程、复制算法、高吞吐Serial Old老年代、单线程、标记-整理适用于大堆、多核ParOld老年代、多线程、标记-整理、低交互CMS老年代、多线程、标记-整理、低停顿低吞吐G1全堆、多线程、标记-整理 附录
「堆栈内存相关」 -Xms 设置初始堆的大小 -Xmx 设置最大堆的大小 -Xmn 设置年轻代大小相当于同时配置-XX:NewSize和-XX:MaxNewSize为一样的值 -Xss 每个线程的堆栈大小 -XX:NewSize 设置年轻代大小(for 1.3/1.4) -XX:MaxNewSize 年轻代最大值(for 1.3/1.4) -XX:NewRatio 年轻代与年老代的比值(除去持久代) -XX:SurvivorRatio Eden区与Survivor区的的比值 -XX:PretenureSizeThreshold 当创建的对象超过指定大小时直接把对象分配在老年代。 -XX:MaxTenuringThreshold设定对象在Survivor复制的最大年龄阈值超过阈值转移到 老年代 「垃圾收集器相关」 -XX:UseParallelGC选择垃圾收集器为并行收集器。 -XX:ParallelGCThreads20配置并行收集器的线程数 -XX:UseConcMarkSweepGC设置年老代为并发收集。 -XX:CMSFullGCsBeforeCompaction5 由于并发收集器不对内存空间进行压缩、整理 所以运行一段时间以后会产生“碎片”使得运行效率降低。此值设置运行5次GC以后对内 存空间进行压缩、整理。 -XX:UseCMSCompactAtFullCollection打开对年老代的压缩。可能会影响性能但是 可以消除碎片 「辅助信息相关」 -XX:PrintGCDetails 打印GC详细信息 -XX:HeapDumpOnOutOfMemoryError让JVM在发生内存溢出的时候自动生成内存快照, 排查问题用 -XX:DisableExplicitGC禁止系统System.gc()防止手动误触发FGC造成问题. -XX:PrintTLAB 查看TLAB空间的使用情况