jvm解决堆内存溢出问题

我们讲一下堆溢出,栈溢出,还有方法区的溢出,这就讲了一个概念,内存溢出和内存泄露的区别是什么,这个概念很混淆,

内存泄露怎么又包含内存溢出,内存溢出和内存泄露又有区别,待会我会细讲的,堆溢出我们怎么去解决,你们基本上都遇到过堆溢出没有,

堆溢出,就是申请的空间不足了,把内存空间加大一点就行了,这个时候我就来演示一把
package com.learn.test;

import java.util.ArrayList;
import java.util.List;

/**
 * 内存溢出问题
 * 初始化加载的比较多
 * 我开始做Spring项目的时候
 * 我刚学JAVA的时候
 * 做SSH进行整合的时候
 * 报了一个内存溢出
 * 去百度找方案
 * 加内存
 * 那时候还没有学JVM
 * 为什么加堆内存大小能解决问题
 * 学JVM的时候才知道整个原理
 * 电脑只有2个G的内存
 * 经常做Spring项目的时候
 * 经常会发生内存溢出的问题
 * 电脑根本跑不起一些项目
 * 这个会出现内存溢出的问题
 * 怎么去演示
 * 这段代码至少需要几兆的空间
 * 这段代码执行至少需要几兆内存的空间大小
 * 至少10M是不是
 * 你们觉得配多少合适呢
 * 有的人说配10M
 * 配10M肯定是不行的
 * 因为它可能会被其他的地方占用空间吗
 * 所以10M肯定不行的
 * 我在这里配置10M看一下
 * -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 这里我的堆的初始值是1M
 * 然后最大是10M
 * 你会发现10M肯定是会有问题的
 * 先运行一遍
 * 默认是可以的,
 * 因为默认值很大
 * 默认是4G内存
 * -Xms1m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 我们配置这个
 * 初始值是1M
 * 最大值是10M
 * 完全不够
 * [Full GC (Allocation Failure) 
 * 而且这个时候有Full GC
 * Full GC表示什么目的
 * 如果你老年代的都不足的情况下,
 * 方法区的内存不足的情况下
 * 或者老年代快满的情况下
 * 它会做一个全部的回收
 * 把新生代和老年代都回收一下
 * 为什么呢
 * 你们在做开发的时候会遇到的
 * 如果你们项目中内存溢出的时候
 * 他首先会做一个Full GC的处理
 * 目的是什么呢
 * 就是把整个新生代和老年代的空间都给你回收一遍
 * 看有没有可回收的
 * [GC (Allocation Failure)
 * 整个GC是什么GC
 * 是Minor GC吗
 * 一般只要发生Full GC就会发生Minor GC
 * 10M肯定不够
 * 我们再改一下
 * 比如15M
 * -Xms1m -Xmx15m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 15M也不一定
 * -Xms1m -Xmx20m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 我们改20M
 * 20M也不够
 * 那我们到底设置多少M合适
 * 我们设置100M
 * -Xms5m -Xmx100m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 100M绰绰有余
 * 而且你们有没有发现问题
 * 当我最大的内存设置的比较大的情况下
 * GC回收是不是不会很频繁
 * 你们看到效果没有
 * 刚才如果我们设置10M,20M的话
 * 至少4次Minor的GC
 * 发生两次Full GC
 * 如果我把最大内存配置为100M的时候
 * 那他只发生1次的新生代的回收
 * -Xms5m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
 * 我们改成50M
 * i:8
 * 运行到第8次的时候,
 * 50M都不够
 * 会有Full GC
 * 我估计还是配100M
 * 
 * 
 * @author Leon.Sun
 *
 */
public class Test0004 {
	public static void main(String[] args) {
		/**
		 * ArrayList数组其实也是有空间的
		 * ArrayList底层是数组
		 * 也是会占空间的
		 * 最大内存值是50M
		 * 这个时候是不是就够了
		 */
//		List<Object> listObject = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			System.out.println("i:" + i);
			Byte[] bytes = new Byte[1 * 1024 * 1024];
			/**
			 * 看到效果没有
			 * 你们在开发中定义的list其实是非常占内存的
			 * 我把list注掉之后就没有很多内存了
			 * [GC (Allocation Failure) [PSYoungGen
			 * 这个GC是什么GC
			 * 是回收新生代还是回收老年代
			 * 记住这是新生代回收
			 * [Full GC (Allocation Failure)
			 * 这个是新生代和老年代一起回收
			 * 他们到底有什么样的区别
			 * 有一些细节参数先不讲
			 * [PSYoungGen: 480K->0K(1536K)] [ParOldGen: 33008K->1017K(4096K)]
			 * 他已经打印出日志了
			 * 今天还没有细分日志的分析
			 * 我们下节课详细分析
			 * [GC (Allocation Failure) [PSYoungGen: 496K->480K(1536K)]
			 * 这个是新生代的日志打印
			 * [Full GC (Allocation Failure) [PSYoungGen: 480K->0K(1536K)] 
			 * 这个是新生代和老年代的日志打印
			 * PSYoungGen这是新生代
			 * ParOldGen这是老年代
			 * 这个为什么要回收
			 * 你可以看一下我是怎么配的
			 * -Xms1m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
			 * 初始值是1兆内存
			 * 因为初始值非常小
			 * 你这里要用10个1M内存
			 * 他需要不停的去回收垃圾
			 * 重新申请内存出来
			 * 就是内存不够的情况下需要去回收垃圾的
			 * 你如果越大的情况下就不会有这些GC日志信息的
			 * 如果我初始值改成50M
			 * -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
			 * 你们可以数一下一共有多少次GC日志
			 * 刚开始是4次,
			 * 现在只要3次
			 * 如果空间非常足
			 * 我就没有必要去回收了
			 * 我内存不足的情况下我再去回收
			 * 垃圾回收的基本原则
			 * 垃圾回收机制基本原则:内存不足的时候回去回收,内存如果足够,暂时不会区回收。 减少回收次数和回收的时间
			 * 因为垃圾回收会对其他的工作线程会有影响的
			 * 就是会暂停一下
			 * 你如果经常频繁的去回收
			 * 非常影响我整个程序的
			 * 你们会发现在生产环境服务器
			 * 一般内存都特别大
			 * 都是8个G,16G
			 * 如果内存够就不会发生垃圾回收
			 * 如果内存非常小垃圾回收就会频繁的去回收
			 * 会非常影响你整个程序的
			 * 回收原则就是减少回收的次数和回收时间
			 * 
			 */
//			 listObject.add(bytes);
		}
		System.out.println("添加成功...");

	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值