Java内存结构:jvm调优 堆调优

什么是堆

是new创建出来的对象或数组存放在堆中。

堆结构图

在这里插入图片描述

堆的参数配置

-XX:+PrintGC 每次触发GC的时候打印相关日志
-XX:+UseSerialGC 串行回收
-XX:+PrintGCDetails 更详细的GC日志
-Xms 堆初始值
-Xmx 堆最大可用值
-Xmn 新生代堆最大可用值
-XX:SurvivorRatio 用来设置新生代中eden空间和from/to空间的比例.
含以-XX:SurvivorRatio=eden/from=den/to
总结: 我们可以直接将初始的堆大小与最大堆大小相等,
这样的好处是可以减少程序运行时垃圾回收次数,从而提高效率。
-XX:SurvivorRatio 用来设置新生代中eden空间和from/to空间的比例.

设置最大堆内存

public class JvmDemo01 {

	public static void main(String[] args) throws InterruptedException {
		byte[] b1 = new byte[1 * 1024 * 1024];
		System.out.println("分配了1m");
		jvmInfo();		
		Thread.sleep(3000);
		byte[] b2 = new byte[4 * 1024 * 1024];
		System.out.println("分配了4m");
		Thread.sleep(3000);
		jvmInfo();

	}
	static private String toM(long maxMemory) {
		float num = (float) maxMemory / (1024 * 1024);
		DecimalFormat df = new DecimalFormat("0.00");// 格式化小数
		String s = df.format(num);// 返回的是String类型
		return s;
	}
	static private void jvmInfo() {
		// 最大内存
		long maxMemory = Runtime.getRuntime().maxMemory();
		System.out.println("maxMemory:" + maxMemory + ",转换为M:" + toM(maxMemory));
		// 当前空闲内存
		long freeMemory = Runtime.getRuntime().freeMemory();
		System.out.println("freeMemory:" +freeMemory+",转换为M:"+toM(freeMemory));
		// 已经使用内存
		long totalMemory = Runtime.getRuntime().totalMemory();
		System.out.println("totalMemory:" +totalMemory+",转换为M"+toM(totalMemory));
	}
}

设置新生代与老年代优化参数

-Xmn 新生代大小,一般设为整个堆的1/3到1/4左右
-XX:SurvivorRatio 设置新生代中eden区和from/to空间的比例关系n/1

设置新生代比例参数

参数: -Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

public class JvmDemo02 {

	 public static void main(String[] args) {
		//-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
		 byte [] b = null;
		 for (int i = 0; i < 10; i++) {
			b =new byte[1*1024*1024];
		 }
	 }
}

内存溢出解决办法

设置堆内存大小

错误原因: java.lang.OutOfMemoryError: Java heap space 堆内存溢出
解决办法:设置堆内存大小 -Xms1m –Xmx10m -XX:+HeapDumpOnOutOfMemoryError

public static void main(String[] args) throws InterruptedException {
		List<Object> list = new ArrayList<>();
		Thread.sleep(3000);
		for (int i = 0; i < 10; i++) {
			System.out.println("i:"+i);
			Byte [] bytes=	new Byte[1*1024*1024];
			list.add(bytes);
		}
		System.out.println("添加成功...");
	}

设置栈内存大小
错误原因: java.lang.StackOverflowError 栈内存溢出
栈溢出 产生于递归调用,循环遍历是不会的,但是循环方法里面产生递归调用, 也会发生栈溢出。
解决办法:设置线程最大调用深度
-Xss5m 设置最大调用深度

public class JvmDemo04 {
	 private static int count;
	 public static void count(){
		try {
			 count++;
			 count(); 
		} catch (Throwable e) {
			System.out.println("最大深度:"+count);
			e.printStackTrace();
		}
	 }
	 public static void main(String[] args) {
		 count();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值