《深入理解java虚拟机》学习笔记

本文深入探讨了Java虚拟机(JVM)中的内存管理机制,包括内存区域划分、内存溢出异常的原因及其避免方法。此外,还介绍了如何利用javap工具进行字节码反汇编以更深入地理解JVM的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

本系列为第一遍阅读的笔记,主要以摘录为主,等后面有一定经验后二刷、三刷,再根据自己经验对一些常用、常见、重点进行举例解释。

阅读目标

本次阅读主要以应付面试为主,目标是对jvm有个大概认知,知道常见面试问题中的答案及相关原理,根据读书内容整理出便于自己理解的思路及相关重点。详细目标如下:

  1. 内存分配和回收策略
  2. GC收集器
  3. GC算法
  4. 判断对象存活的方法
  5. 类加载器
  6. 类加载机制(类的加载过程)
  7. 类加载机制(类的初始化)
    (文末列出了网络上其它主要博文)

源码下载

github

概要

这里有一篇整理的不错的图
原文链接
这里写图片描述

第一章

// 略

第二章

通过本章的学习,我们明白了虚拟机里面的内存是如何划分的,哪部分区域、什么样的代码和操作可能导致内存溢出异常。虽然Java有垃圾收集机制,但内存溢出异常离我们并不遥远, 本章只是讲解了各个区域出现内存溢出异常的原因
下一章将详细讲解Java垃圾收集机制为了避免内存溢出异常的出现都做了哪些努力。

拓展阅读
通过javap反汇编字节码文件,获取jvm执行的汇编代码文件,来反推jvm执行过程,进一步理解jvm内部栈、堆工作步骤和原理
javap的基本用法
java指令集

虚拟机里面的内存是如何划分的

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述
jvm内存模型

哪部分区域、什么样的代码和操作可能导致内存溢出异常

  1. 2-3:不断创建无法自动回收的对象,导致后续操作无法获得更多足够内存抛出OutOfMemoryError异常
  2. 2-4:栈深度超过虚拟机允许最大深度,抛出StackOverflowError异常
/**
 * 2-3 
 * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * @author zzm
 */
public class HeapOOM {

	static class OOMObject {
	}

	public static void main(String[] args) {
		List<OOMObject> list = new ArrayList<OOMObject>();

		while (true) {
			list.add(new OOMObject());
		}
	}
}
/**
 * 2-4
 * VM Args:-Xss128k
 * @author zzm
 */
public class JavaVMStackSOF {

	private int stackLength = 1;

	public void stackLeak() {
		stackLength++;
		stackLeak();
	}

	public static void main(String[] args) throws Throwable {
		JavaVMStackSOF oom = new JavaVMStackSOF();
		try {
			oom.stackLeak();
		} catch (Throwable e) {
			System.out.println("stack length:" + oom.stackLength);
			throw e;
		}
	}
}
/**
 * 2-5
 * VM Args:-Xss2M (这时候不妨设大些)
 * @author zzm
 */
public class JavaVMStackOOM {
 
       private void dontStop() {
              while (true) {
              }
       }
 
       public void stackLeakByThread() {
              while (true) {
                     Thread thread = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                   dontStop();
                            }
                     });
                     thread.start();
              }
       }
 
       public static void main(String[] args) throws Throwable {
              JavaVMStackOOM oom = new JavaVMStackOOM();
              oom.stackLeakByThread();
       }
}

/**
 * 2-6
 * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M
 * @author zzm
 */
public class RuntimeConstantPoolOOM {
	public static void main(String[] args) {
		// 使用List保持着常量池引用,避免Full GC回收常量池行为
		List<String> list = new ArrayList<String>();
		// 10MB的PermSize在integer范围内足够产生OOM了
		int i = 0; 
		while (true) {
			list.add(String.valueOf(i++).intern());
		}
	}
}
/**
 * 2-7
 * VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M
 * @author zzm
 */
public class RuntimeConstantPoolOOM {

	public static void main(String[] args) {
		public static void main(String[] args) {
		String str1 = new StringBuilder("中国").append("钓鱼岛").toString();
		System.out.println(str1.intern() == str1);
		
		String str2 = new StringBuilder("ja").append("va").toString();
		System.out.println(str2.intern() == str2);
	}	}
}
/**
 * 2-8
 * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M
 * @author zzm
 */
public class JavaMethodAreaOOM {
	public static void main(String[] args) {
		while (true) {
			Enhancer enhancer = new Enhancer();
			enhancer.setSuperclass(OOMObject.class);
			enhancer.setUseCache(false);
			enhancer.setCallback(new MethodInterceptor() {
				public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
					return proxy.invokeSuper(obj, args);
				}
			});
			enhancer.create();
		}
	}

	static class OOMObject {

	}
}
/**
 * 2-9
 * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M
 * @author zzm
 */
public class DirectMemoryOOM {

	private static final int _1MB = 1024 * 1024;

	public static void main(String[] args) throws Exception {
		Field unsafeField = Unsafe.class.getDeclaredFields()[0];
		unsafeField.setAccessible(true);
		Unsafe unsafe = (Unsafe) unsafeField.get(null);
		while (true) {
			unsafe.allocateMemory(_1MB);
		}
	}
}

参考资料

《JVM常见面试题及答案》https://blog.youkuaiyun.com/zd836614437/article/details/64126826

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值