配置jvm堆最大内存&eden区与s0或者s1区域比例

配置堆内存大小,其实比较简单,你们以后做JVM调优,主要是围绕着哪个内存区域,都是围绕着堆内存的,像栈每次

用完之后都会自动释放的,还有方法区,但是方法区你不用考虑,因为它如果满的情况下,垃圾回收会自动去回收,但是主要还是围绕

堆内存的,我们怎么去配置堆内存大小,在这里给你们介绍几个方法
package com.learn.test;

/**
 * 我们怎么去配置堆内存大小
 * 打印一下堆内存的一些基本的大小
 * @author Leon.Sun
 *
 */
public class Test001 {

	public static void main(String[] args) {
		/**
		 * 4 * 1024 * 1024这样是4个兆的空间
		 * 你们猜一下已使用内存是多少兆
		 * 是不是至少在9M以上
		 * 5家4嘛
		 * 可不可能小于9兆
		 * 肯定是大于9M以上
		 * 你们想想是不是这样的
		 * 已经使用内存10M
		 * 我们运行是不是这样的
		 * 10M
		 * 为什么会多出1兆出来
		 * 因为它底层也会做一些处理操作的
		 * 可能有误差
		 * 但是误差不大
		 * 一般在几兆左右
		 * 肯定是会大于9M以上的
		 * 这个是堆内存大小
		 * 过来我会将内存泄露怎么解决
		 * 这个配置JVM堆内存的大小应该不难吧
		 * 我这里能不能配置25M
		 */
		// byte[] b = new byte[4 * 1024 * 1024];
		/**
		 * 我能不能申请25M的空间
		 * java.lang.OutOfMemoryError: Java heap space
		 * 这个你们遇见过是不是
		 * 我只是演示一个效果
		 * 待会讲怎么解决
		 * 一开始的时候为什么不会溢出
		 * -Xmx20m -Xms5m
		 * 我把这个配置删掉
		 * 因为一开始默认是4个G的内存
		 * 这绰绰有余
		 * 肯定是没有任何影响的
		 * 你看这个就没有溢出了
		 * 堆内存配置的话比较容易
		 * 
		 */
		byte[] b = new byte[25 * 1024 * 1024];
		System.out.println("分配了25M空间给数组");

		/**
		 * 打印JVM一些基本的参数
		 * 第一个参数表示堆的最大内存
		 * 最大内存1803M
		 * 你们知道他们是按照什么单位来换算的
		 * 兆的下一个单位是字节
		 * 他这个比较小
		 * 你们最好是/1024/1024
		 * 这样就换算成兆了
		 * 你们看到1803M
		 * 1803M大概等于多少G呢
		 * 差不多2个G
		 * 可能有一些内存被占用掉了
		 * 默认是4个G的
		 * 可能你的电脑打印出来也不一样
		 * 因为每台电脑都不一样
		 * 所以多多少少会有点误差
		 * 你们都按照四舍五入去算就行了
		 * 默认都是4个G的内存
		 * 我以前带电脑是8个G的时候默认是8个G的
		 * 这是默认的
		 * -Xmx20m -Xms5m
		 * 这个参数什么意思
		 * 表示我当前最大可用堆内存是20M
		 * 然后初始的是为5M
		 * 你们找到Run as里面
		 * 然后Run Configuration
		 * 然后你把参数就放到Arguments的VM arguments
		 * 表示我这个项目启动起来之后,
		 * 他最大的堆内存是20M
		 * 他的初始值是5M
		 * 
		 * 最大内存18M
		 * 有的人说不对啊
		 * 我明明设置的是20M
		 * 怎么变成18M了
		 * 我已经讲过了
		 * 这个多多少少会有点误差
		 * 但是大家不要去纠结这个误差
		 * 
		 */
		System.out.println("最大内存" + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");
		/**
		 * 第二个可用的内存
		 * 可用内存96M
		 * 默认可用的是96M
		 * 
		 * 可用内存4M
		 */
		System.out.println("可用内存" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "M");
		/**
		 * 已经使用的内存
		 * 已经使用内存123M
		 * 
		 * 已经使用内存5M
		 * 这个时候可以看到已经使用的内存是5M
		 * 这个已经使用的内存是什么意思吗
		 * 已使用的内存是根据你初始值申请来的
		 * 你在这边可以看一下
		 * -Xmx20m -Xms5m
		 * 在这边我申请的初始值是5m
		 */
		System.out.println("已经使用内存" + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "M");
	}
	
}
首先这个是堆内存,堆内存新生代和老年代一般是1:2,左边我们叫做新生代,右边叫做老年代,新生代又有一个eden区,

接着还有S0区和S1区,S0还有一个名字叫from区,默认的是8:1:1,这个看你们公司,每个公司的项目不一样,eden区比S0区大了还是小了

记住肯定是要大的,S0区和S1区的主要作用是干嘛,做复制功能,你没必要把它搞的特别大,特别大的情况下会特别的占用内存的,

所以默认情况是8:1:1,其实8:1:1也不是很好,如果我对象特别多的情况下,你如果还是做成8:1:1的情况下,你知道会产生什么情况吗,

s0区可能装不满的,所以也会导致频繁的GC的回收,所以要看你在什么应用场景,我看过我们的项目是怎么配的呢,就是2:1:1,

但是我们的项目比较大,绝大部分的对象还是会存放到老年代里去的,根据不同的公司,这个看你们公司的,我们配置新生代的比例,

我们讲一个参数,-XX:+PrintGCDetails这个参数,这个参数谁知道是干嘛用的,打印详细的GC日志,GC日志到时给你演示一遍,当它

发生GC回收的时候,都会打印一个GC日志

 

package com.learn.test;

/**
 * 配置新生代比例大小
 * 什么是新生代
 * 我们刚出生的都是在eden区里面
 * 如果eden区满的时候会GC的
 * @author Leon.Sun
 * -Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
 * 首先堆内存是20M
 * 堆内存最大值是20M
 * 新生代-Xmn最大值是1M
 * eden区和s0/s1区的比例是2:1
 * -XX:SurvivorRatio这个参数干嘛用的
 * 它是配置eden区和from/to区的一个比列
 * 用来设置新生代eden空间和from/to空间的比例
 * from区和to区的比例都是相等的
 * 相当于eden区占两份,
 * S0区占一份,S1区也占一份
 * 第一次你是看到配置的选项的,
 * 你要先运行这个JAVA代码
 * 然后你就可以去Run as -> Run Configration看到记录
 * 然后你就可以配置VM arguments
 * 这个说细点
 * 免得你们下次不知道怎么配了
 * -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
 * [GC (Allocation Failure) [DefNew: 1024K->512K(1536K), 0.0014710 secs]
 * 这个表示空间不够了进行回收垃圾
 * 首先你们可以看到这几个参数
 * eden space 1024K
 * 首先可以看到eden区
 * eden区是1024K
 * from space 512K
 * from区是512K
 * to   space 512K
 * to区是512K
 * -XX:SurvivorRatio=2这个参数配置什么意思
 * SurvivorRatio=2 配置新生代中 eden from to 比例关系 2 1 1
 * 1024K除以2是不是512K了
 * -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
 * 我们把这个配置删掉
 * 我们只留-XX:+PrintGCDetails -XX:+UseSerialGC这个信息
 * 只留GC的日志信息
 * -XX:+UseSerialGC这个是配置串行回收
 * 这个时候我们来运行一遍来看这个效果
 * 你们有没有发现一个问题
 * 这一次运行没有发生GC回收的
 * 你们有没有仔细观察
 * -Xms20m -Xmx20m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
 * 我这个时候把堆内存设置为20M
 * 堆内存最大内存为20M的情况下
 * 他就会发生一个GC日志[GC (Allocation Failure)
 * 那这个GC日志是什么GC
 * 你们说这个程序运行的时候需要几兆
 * 运行的时候至少是需要10M以上
 * 因为我循环了10次
 * 但是你新生代只有2m
 * 你新生代是2兆
 * 这个时候你又要装10兆
 * 你要往新生代放10次2M的话
 * 新生代空间根本就不够
 * 因为新生代只有2M内存
 * 这样我就不够用
 * 为了防止内存溢出的情况下
 * 包括防止内存泄露的情况下
 * 我就不停的进行回收
 * 这样我才有新的可以进来
 * 如果内存不足的情况下会发生不断地去进行回收的
 * 如果内存非常足的情况下他去回收干嘛
 * 类似与我们生活中你那么有钱你还要去抢钱干嘛
 * 其实是一个道理
 * 你们可以算一下
 * 默认的我们可以算一下
 * 34944K除以4352K等于8
 * 你们觉得这个比例是多少
 * 8:1:1
 * eden:from:to
 * 你们如果仔细算有点误差也是很正常的
 * 不要纠结少了几十K
 * 这个很正常
 * 
 */
public class Test002 {

	public static void main(String[] args) {
		byte[] b = null;
		for (int i = 0; i < 10; i++) {
			b = new byte[1 * 1024 * 1024];
		}

	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值