赞
踩
因为方法区的大小是有限制的,而且方法区的GC回收效率太低,当字符串常量池中存储的字面量数量不断增加时,会导致方法区内存不足,从而导致OutOfMemoryError异常。调整到了Java堆内中也是为了更好的解决这个问题,通过Full GC的时候,额外调用字符串常量池的对应接口做可达性分析,将不可达的String对象的引用字符串常量池中移除掉并销毁其指向的String对象。
执行引擎是Java虚拟机核心组件之一,主要负责将Java字节码转换为机器指令,并执行这些指令。其主要任务包括:
运行期
确认的,因此大小不固定。一般堆大小远远大于栈。编译期
就确认,大小是固定的。ClassName objectName = new ClassName();
ClassName objectName(argument1, argument2, ...) {
// 构造函数的代码
}
ClassName objectName = (ClassName) sourceObject.clone();
FileInputStream fis = new FileInputStream("objectFile");
ObjectInputStream ois = new ObjectInputStream(fis);
ClassName objectName = (ClassName) ois.readObject();
需要注意的是,对象创建的流程是由Java虚拟机自动完成的,程序员只需要通过new关键字来创建对象即可,不需要手动管理对象的生命周期。
指针碰撞的优点是实现简单,适用于内存分配比较均匀的场景。但是,在内存分配不均匀的情况下,指针碰撞会导致内存碎片化,从而影响程序的性能。
空闲列表的优点是能够有效地避免内存碎片化,从而提高内存分配的效率。但是,空闲列表的实现比较复杂,需要维护一个空闲列表和一个哈希表,而且需要考虑并发访问的问题。
对象的创建在虚拟机中是一个非常频繁的行为,哪怕只是修改一个指针所指向的位置,在并发情况下也是不安全的,可能出现正在给对象 A 分配内存,指针还没来得及修改,对象 B 又同时使用了原来的指针来分配内存的情况。解决这个问题有两种方案:
锁分段技术虽然能够保证多线程并发安全。但是,锁分段技术的实现比较复杂,需要维护一个锁数组和一个内存块链表,而且会产生较多的上下文切换和锁竞争。
TLAB技术的实现比较简单,能够减少锁竞争和上下文切换,从而提高程序的性能。但是,TLAB技术需要占用额外的内存空间,并且需要对TLAB缓存进行管理和维护,否则会导致内存泄漏和性能下降。
Java 程序需要通过 JVM 栈上的reference访问堆中的具体对象。对象的访问方式取决于 JVM 虚拟机的实现。目前主流的访问方式有句柄
和 直接指针
两种方式。
使用句柄方式的优点在于栈里面的reference存储的是稳定不变的句柄地址,如果对象的地址发生变化,只需更新句柄池中存放的对象地址就好,reference中存储的句柄地址无需变动。缺点就是会产生一次间接访问的开销,效率相对较低。直接指针的优点就在于无需间接访问的开销,效率较高。缺点就是当对象地址发生变化时,需要手动更新栈里面的指针的值,在多线程编程中会存在安全问题。
内存泄漏(Memory Leak)是指程序在使用动态分配内存时,由于某些原因未能及时释放已分配的内存,导致这部分内存无法被再次使用,从而浪费了宝贵的系统资源。
通常情况下,内存泄漏是由程序员在编写代码时出现的错误导致的。例如,程序中可能存在未被正确关闭的文件、数据库连接、网络连接等资源,这些资源在使用后应该被及时释放,否则就会导致内存泄漏。
内存泄漏的危害很大,它会导致系统的内存资源逐渐减少,直到最终系统崩溃。因此,程序员在编写代码时应该注意及时释放已分配的内存资源,避免出现内存泄漏问题。
内存溢出(Memory Overflow)是指程序在使用动态分配内存时,申请的内存空间超出了系统可用的内存大小,导致程序无法正常运行。
通常情况下,内存溢出是由程序员在编写代码时出现的错误导致的。例如,程序中可能存在申请的内存空间大小计算错误、数组越界等问题,这些问题都可能导致程序申请的内存空间超出系统可用的内存大小,从而导致内存溢出。
内存溢出的危害很大,它会导致程序崩溃或者系统崩溃,甚至可能会导致数据丢失或者系统安全问题。因此,程序员在编写代码时应该仔细检查内存申请和使用的代码,避免出现内存溢出问题。此外,也可以通过增加系统可用内存大小、优化程序代码等方式来解决内存溢出问题。
Java垃圾回收机制是一种自动内存管理机制,它可以自动检测不再被程序所使用的对象并将其回收,从而释放内存空间,避免了内存泄漏和内存溢出等问题。
不能,虽然可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC的执行。
Object object = new Object();
String str = "StrongReference";
SoftReference<String> softRef = new SoftReference<String>(str);
WeakReference<String> abcWeakRef = new WeakReference<String>(str);
ReferenceQueue phantomQueue1 = new ReferenceQueue();
PhantomReference<Object> sf1 = new PhantomReference<>(new Object(), phantomQueue);
在Java中,GC的触发时机通常由垃圾回收器自行决定,JVM会根据当前的内存使用情况和垃圾回收器的策略,动态地调整垃圾回收器的触发时机。一般来说,垃圾回收器会在以下情况下触发GC:
需要注意的是,垃圾回收器的触发时机对于程序的性能和稳定性都有着重要的影响。如果垃圾回收器的触发时机不当,可能会导致程序出现频繁的Full GC,甚至导致程序崩溃。因此,在实际开发中,需要根据具体情况选择合适的垃圾回收器,并对垃圾回收器的参数进行适当的调整,以达到最佳的性能和稳定性。
Young GC(Young Generation Garbage Collection)也称为Minor GC,是指对Java堆中新生代(Young Generation)中的垃圾对象进行回收的垃圾回收过程。当应用程序向堆中申请内存时,如果没有足够的空间,就会触发一次Young GC。Young GC会扫描新生代中的所有对象,将那些已经不再被引用的对象回收掉,并将还存活的对象复制到Survivor区或晋升到老年代中。
Young GC相对于Full GC来说,执行速度更快,因为它只需要扫描和回收新生代中的垃圾对象,而不需要扫描和回收整个堆内存。但是,Young GC的回收效率可能会受到一些因素的影响,例如新生代的大小、Survivor区的大小、对象的年龄等等。如果Young GC的频率过高,就可能会导致应用程序的性能下降,因为它会消耗大量的CPU资源和内存带宽。
为了优化Young GC的效果,可以通过调整JVM参数来改变新生代的大小、Survivor区的大小、对象的年龄阈值等等,以达到更好的垃圾回收效果。
Full GC是指Full Garbage Collection的缩写,也称为全局垃圾回收。在Full GC过程中,Java虚拟机会对整个Java堆中的对象进行垃圾回收,包括新生代和老年代中的所有对象,以确保对整个Java堆中的对象进行一次全面的扫描和清理。
Full GC的执行通常会伴随着较长的停顿时间,因为它需要对整个Java堆内存区域进行扫描和清除。为了减少Full GC的执行频率和停顿时间,可以采用一些优化技术,如调整Java堆内存大小、调整垃圾回收器的参数等。
Full GC通常是在Young GC无法完成对所有垃圾对象的回收时触发的。以下是可能会触发Full GC的情况:
常见的垃圾收集算法有:复制算法、标记 -清除算法、标记-整理算法、分代算法,我们常用的垃圾回收器一般都采用分代算法。
java -Xms512m -Xmx1024m MyApp
export JAVA_OPTS="-Xms512m -Xmx1024m"
java MyApp
-Xms512m
-Xmx1024m
无论使用哪种方式,都需要注意JVM启动参数的正确性和合理性。不当的JVM启动参数可能会导致JVM性能下降或者出现其他异常情况。
类加载执行过程是Java虚拟机(JVM)中的一个重要概念,它指的是将Java类的字节码文件加载到内存中,并将其转换为Java对象的过程。类加载执行过程主要包括以下几个步骤:
需要注意的是,类加载执行过程是一个递归的过程,每个类都会在其父类加载完成后再进行加载和初始化。同时,类加载器也是一个重要的概念,它负责加载和管理类的加载过程。在实际开发中,需要了解类加载执行过程和类加载器的原理,以便能够更好地进行调试和优化。
Java中的类加载器(ClassLoader)是一个重要的概念,它负责加载和管理Java类的加载过程。常见的Java类加载器包括:
双亲委派模型指的是当一个类加载器需要加载一个类时,它会首先委派给父类加载器去加载,如果父类加载器可以加载该类,则直接返回;如果父类加载器无法加载该类,则交给自己去加载。在双亲委派模型中,每个类加载器都有一个父类加载器,它们形成了一个类加载器的层次结构。
JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。第三方有:MAT(MemoryAnalyzerTool)、GChisto。
// 显示系统各个进程的资源使用情况
top
// 查看某个进程中的线程占用情况
top -Hp pid
// 查看当前 Java 进程的线程堆栈信息
jstack pid
// 查看当前的 JVM 参数配置
ps -ef | grep java
// 查看 Java 进程的配置信息,包括系统属性和JVM命令行标志
jinfo pid
// 输出 Java 进程当前的 gc 情况
jstat -gc pid
// 输出 Java 堆详细信息
jmap -heap pid
// 显示堆中对象的统计信息
jmap -histo:live pid
// 生成 Java 堆存储快照dump文件
jmap -F -dump:format=b,file=dumpFile.phrof pid
top
ps -mp pid -o THREAD,tid | sort -r
printf "%x\n" tid
jstack pid |grep tid -A 50
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。