`

JVM参数浅析

 
阅读更多

后续的JVM参数分析都在这里整理

#-Xss1m 设置每个线程的堆栈大小

#-XX:+UseParNewGC 设置年轻代为并行收集。

#-XX:+UseConcMarkSweepGC 设置并发收集器

#-XX:+CMSParallelRemarkEnabled 表示并行remark

#-XX:+UseCMSCompactAtFullCollection  打开对年老代的压缩。可能会影响性能,但是可以消除碎片

#-XX:+UseFastAccessorMethods 原始类型的快速优化

#-XX:+UseCMSInitiatingOccupancyOnly 使用手动定义初始化定义开始CMS收集

#-XX:+UseCompressedOops

#-XX:-ReduceInitialCardMarks

#-XX:CMSInitiatingOccupancyFraction=75

#-XX:SurvivorRatio=3   survivor和eden的比值为1:3  

#-XX:+DisableExplicitGC

#-XX:-UseAdaptiveSizePolicy

 

1.-Xms100m -Xmx100m

   ms:minus即最小内存,jvm启动的时候初始化内存,如果ms和mx不相同则jvm的内存会根据使用情况动态调整,一般设置两个值相同。

  ms,mx的内存是指young和tenured两块的内存,有些blog说这个是整个jvm的内存包含permgen的内存,实际是不正确的。可以通过jstat -gc来计算出来的,详情见截图。

  S0C+S1C+EC+OC=102400也就是100M

    

 


 

 

 

 2.-Xmn 指定young内存的大小 

    指定-Xmn50M 通过计算就可以得出young和old区域分别是50M

   

 

 

 

 3.-XX:PermSize  -XX:MaxPermSize

   -XX:PermSize jvm初始化永久代的大小,-XX:MaxPermSize jvm最大的永久代大小。

   此处设置100M可以看出来永久代的确是100M。young和tunured堆内存不受影响。


 

 

4.-XX:NewRatio=4

   设置young和tenured的比值1:4   100M的话则tenured的内存为80M。
   

 



 

 

5.-XX:SurvivorRatio=3

   survivor和eden的比值为1:3   所以survivor占用内存的1/5。

   

 



 

 6.-XX:MaxTenuringThreshold=n

  设置对象在young区域复制的次数,超过这个次数存活的对象拷贝至old区域。

   验证这个参数,过程还是挺纠结的,先把纠结的过程记录下吧,测试代码如下。

   

public class TestOOM {

	public static void main(String[] args) throws InterruptedException {
		
		List list=new ArrayList();
		OOM oom=new OOM();
		Thread.sleep(20*1000);
		for(int i=0;i<15;i++){
	//		System.out.println(i);
	//		list.add(new OOM());
	    OOM xx=new OOM();
	    xx=null;
			Thread.sleep(2*1000);
		}
		
	}
	
}

class OOM{
	
	byte[] bytes=new byte[1024*1024*8];
	
}

 

     第一次尝试,

     java -Xms100M -Xmx100M -Xmn30M -XX:SurvivorRatio=1  TestOOM

     heap分配100M,young 30M XX:SurvivorRatio=1这样eden,survivor都是10M了。预想第一次分配的8M对象进入Eden,后面再分配对象的时候肯定会出现minor gc,这样不断的分配对象,不断的设置成null,这样就会不断的出现minor gc超过一定的次数就会进入tenured区域。可是发现实际的结果还是与想象的差别很大,因为对象直接就在tenured区域中分配了,而且tenured区域满的时候开始minor gc了。

      

 

    确实大对象会直接进入tenured区域,这就引出了另外一个参数, -XX:PretenureSizeThreshold,这个参数的值只能是B,字节。

    第二次尝试,可以设置超过10M的对象才能进入tenured区域。

    java -Xms100M -Xmx100M -Xmn30M -XX:SurvivorRatio=1  -XX:PretenureSizeThreshold=10485760  TestOOM

     不过发现这个参数不灵光,这个8M的对象还是直接进入了tenured区域。也是上面的现象tenured区域满的时候开始minor gc了。

     

  

      哎,这个参数不灵光啊,突然又有个新的想法,为何不把tenured区域的参数设置小于8M,这样用户不就进不去了,这样不就一直在young区域gc了吗,此时小小得意了一下,心想这不就没有问题了。

 

     第三次尝试,

     java -Xms35M -Xmx35M -Xmn30M -XX:SurvivorRatio=1  -XX:MaxTenuringThreshold=10   TestOOM

     

 

   虽然这次按照预想的在young区域进行minor gc但是又有新的问题啦,minor gc 6次之后竟然报oom。

 

   所以怀疑是不是jvm内部机制如果minor gc 6次内存没有减的话就会报错,于是乎猜想如果-XX:MaxTenuringThreshold=3是不是三次之后就会将对象进入tenured区域,但是此时发现tenured区域没有足够的空间此时会抛oom错误呢。

    

    第四次尝试,

    java -Xms35M -Xmx35M -Xmn30M -XX:SurvivorRatio=1  -XX:MaxTenuringThreshold=3   TestOOM

    还是以失败告终啊,竟然还是minor gc 6次之后才报错啊,是在不明白了,有大神给解读下这是为什么吗?

 

 

  • 大小: 4 KB
  • 大小: 3.6 KB
  • 大小: 1.1 KB
  • 大小: 3.5 KB
  • 大小: 1.4 KB
  • 大小: 5.6 KB
  • 大小: 1 KB
  • 大小: 3.1 KB
  • 大小: 1 KB
  • 大小: 3 KB
  • 大小: 20.8 KB
  • 大小: 20.6 KB
  • 大小: 11.4 KB
  • 大小: 2.9 KB
1
0
分享到:
评论

相关推荐

    浅析打开eclipse出现Incompatible JVM的解决方法

    在Eclipse的安装目录下找到`eclipse.ini`文件,添加或修改`-vm`参数指向新安装的JDK的`bin`目录下的`javaw.exe`或`java.exe`。 通过上述方法,通常可以成功解决Eclipse启动时出现的“Incompatible JVM”问题。在...

    浅析JVM逃逸的原理及分析

    方法逃逸是指在一个方法体内,定义一个局部变量,而它可能被外部方法引用,比如作为调用参数传递给方法,或作为对象直接返回。线程逃逸是指这个对象被其他线程访问到,比如赋值给了实例变量,并被其他线程访问到了。...

    浅析JAVA之垃圾回收机制.doc

    通过合理设置JVM参数,我们可以优化内存使用,减少垃圾回收带来的性能影响,同时避免依赖不确定的`finalize()`方法来管理资源。在开发Java应用时,应尽量减少对垃圾回收机制的干预,让JVM自行管理内存,以实现更高效...

    Java中main()方法浅析.docx

    ### Java中main()方法浅析 #### 一、概述 在Java编程语言中,`main()`方法具有特殊的意义,它是所有Java应用程序的起点。当Java虚拟机(JVM)启动并加载了一个包含`main()`方法的类时,它会自动调用这个方法来开始...

    浅析java程序入口main()方法

    这个参数是由JVM负责赋值的,JVM会将命令行参数传递给这个数组。例如,在dos命令行中运行Java程序时,可以在类名后加上一个或者多个字符串(以空格隔开),这时JVM会依次将这些数值赋给args数组。 main()方法的...

    浅析JAVA异常处理机制.pdf

    ### 浅析JAVA异常处理机制 #### 一、Java异常处理机制概述 异常处理是Java语言中的一个重要机制,它能够确保程序在遇到不可预料的情况时仍能维持稳定运行。异常处理主要包括三个方面:捕获异常、控制程序流程以及...

    Java中文乱码浅析及解决方案

    在启动JVM时,添加`-Dfile.encoding=UTF-8`参数,确保整个运行环境使用UTF-8编码。 其次,当涉及文件读写或网络数据传输时,输出流和输入流的编码必须与预期编码一致。例如,当我们写入文件时,应明确指定输出流的...

    Java中堆内存与栈内存分配浅析

    ### Java中堆内存与栈内存分配浅析 #### 一、引言 在Java编程语言中,内存管理是一项至关重要的技术。程序运行时所使用的内存主要分为两类:堆内存(Heap Memory)和栈内存(Stack Memory)。理解这两种内存类型的...

    Notes:This is a learning note | Java基础,JVM,源码,大数据,面经

    Notes 我的笔记: 知识不总结,就会被大脑当垃圾清理 :horse:求知之路必然不会...Apache的MaxClients参数详解及其在Tomcat执行FullGC时的影响 JavaEE 浅析Web容器 计算机网络 UDP&TCP DB MySQL索引背后的数据结构

    浅析Java中的final关键字Java开发Java经验技

    这在定义常量时非常有用,例如在数学公式或配置参数中。例如: ```java final double PI = 3.14159; ``` 这里的`PI`变量一旦赋值后,就无法更改。`final`常量在类加载时会被静态初始化,确保了其在整个程序运行...

    浅析java class 文件

    方法表包含了方法的访问控制标志、返回类型、名称、参数列表和字节码指令等。 6) 属性:属性(Attribute)是Class文件中的元数据,可以提供额外的信息,如方法的异常处理、代码行数、注解等。JVM规范定义了一些标准...

    java字节码框架ASM操作字节码的方法浅析

    字节码的表示方式通常使用类型签名,这是JVM用来表示方法参数和返回值类型的字符串形式。 类型签名是一种规范,例如`long f (int n, String s, int[] arr)`的类型签名是`f(ILjava/lang/String;[I)J`,它由方法名、...

    浅析Java中的 new 关键字

    1. 分配内存:Java虚拟机(JVM)在堆内存中为新对象分配所需的空间。这个过程包括为对象的所有字段分配内存。 2. 初始化:接下来,对对象的成员变量进行默认初始化。例如,基本类型变量会被赋予默认值,引用类型...

    Java中BEAN与EJB的区别浅析

    2. 具有一个无参数的构造器,以便容器可以实例化Bean。 3. 实现`Serializable`接口,以便支持序列化,实现对象持久化。 4. 属性通常是私有的,通过getter和setter方法进行访问控制。 5. 可能包含事件监听器和属性...

    浅析使用JDBC操作MySQL需要添加Class.forName("com.mysql.jdbc.Driver")

    `Class.forName()`方法内部调用了本地方法`forName0`,并传入了一个布尔参数`initialize`,默认值为`true`,表示在加载类之后执行初始化。初始化阶段不仅包括对类变量的赋值,还包括执行静态初始化块,对于父类也是...

    浅析Java中线程的创建和启动

    这样,你可以将Runnable对象作为参数传递给Thread类的构造函数,创建Thread对象,然后启动线程。 ```java public class MyRunnable implements Runnable { @Override public void run() { // 这里编写线程要执行...

    JNI资源汇总

    JNI是一个规范,它定义了Java虚拟机(JVM)如何与本地代码(通常为C/C++)交互。通过JNI,Java程序员可以调用本地方法,反之,本地代码也可以调用Java方法。 2. **JNI的用途**: - **性能提升**:对于计算密集型...

    JSTL详细标签库介绍

    &lt;BR&gt;3、常见异常实例包括:数组下标越界,算法溢出(超出数值表达范围),除数为零,无效参数、内存溢出异常处理功能:主要处理一些同步异常(除数为0),不宜处理一些异步事件(Disk I/O End、网络信息到达、点击...

Global site tag (gtag.js) - Google Analytics