JVM优化技巧
- 调整堆内存大小:JVM运行时会占用一定的内存空间,保证在分配内存时不会因为内存不足而导致系统崩溃。在分配堆内存时会根据实际情况进行自适应调整,但是过小的内存会导致频繁的GC,过大的内存则会造成内存空间的浪费。
- 调整GC(垃圾回收)策略:JVM有多种GC策略,如Serial GC、Parallel GC、CMS GC和G1 GC等,每种GC策略都有适用的场景,需要根据实际情况进行选择。
- 避免死循环和无限递归:死循环和无限递归会导致内存溢出,需要谨慎编写代码。
- 避免频繁创建和销毁对象:频繁创建和销毁对象会导致GC频繁执行,需要尽量重用对象。
- 使用局部变量替代全局变量:局部变量的生命周期比全局变量短,可以减少对象生命周期的时间,从而降低GC的频率和内存占用。
- 尽量避免使用finalize()方法:finalize()方法会在垃圾回收时被调用,但是由于垃圾回收时间无法预知,会造成内存泄漏。
Java堆
Java堆是JVM管理的内存中最大的一块,用于存放对象实例。Java堆空间是由JVM在启动时创建的,可以通过-Xmx和-Xms参数来设置最大堆大小和初始堆大小。
Java堆可以被分为新生代和老年代两部分。
新生代
新生代是Java堆中占用空间比较小的一部分,主要用于存放新创建的对象。新生代又可以分为Eden区、Survivor 0区和Survivor 1区三部分。
Eden区是新生代中最大的一块空间,用于存放新创建的对象,当Eden区满时,未死亡的对象会被移到Survivor区,如果Survivor区也满了,则会进行Minor GC(年轻代GC),将存活的对象放入另一个Survivor区,并清空当前Survivor区和Eden区。
老年代
老年代是Java堆中占用空间比较大的一部分,主要用于存放长生命周期和大对象,当对象在新生代进行了多次GC后仍然存活,就会被移到老年代,当老年代空间不足时会进行Full GC(全局GC),将无用的对象清除掉。
代码详解
下面是一个简单的Java程序,用于创建并输出一个字符串对象:
public class Test {
public static void main(String[] args) {
String str = "Hello World";
System.out.println(str);
}
}
在JVM中,该程序的运行过程如下:
- JVM启动时会创建Java堆,包括新生代和老年代。
- 程序开始执行时,会在Java堆中创建一个字符串对象,并将其引用赋值给str变量。
- 程序执行输出语句时,会将str变量的引用传递给System.out.println()方法,该方法会从Java堆中获取字符串对象,并输出该对象的内容。
- 程序执行结束后,JVM会进行垃圾回收,将无用的对象从Java堆中清除掉。