JAVA内存

最近发现关于JVM知识空白,从网课和各大网站学习整理一些,作为记录。

一、运行时数据区:
在这里插入图片描述

线程共享:方法区、堆
线程私有:虚拟机栈、本地方法栈、程序计数器

程序计数器:是一块较小的内存空间,作用可以看做是当前线程所执行的字节码的行号的指示器,线程私有;

JVM方法栈和本地方法栈:在sun的jdk中,JVM方法栈和本地方法栈是算在一起的,虚拟机栈为虚拟机执行JAVA方法,本地方法栈为虚拟机执行Native方法,线程私有。

java heap:是虚拟机中内存区域最大的一块,细分可以分为新生代和老年代,新生代可以划分为Eden、S0、S1,线程共享。

方法区:存放了要加载的类的信息,类中的静态变量,定义为final的常量,类中的Field信息,方法信息等,全局共享,又叫做持久带,可以通过-XX:PermSize和-XX:MaxPermSize设置最小值和最大值,线程共享。【1.8以后没有perm,变更为MateSpace】

二、JVM各区的作用
在这里插入图片描述

新生代:
大多数情况下,java中新建的对象都是在新生代上分配的,新生代由Eden和两块相同大小的S0和S1组成,其中S0和S1又成为From和To,可以通过-Xmn来设置新生代的大小,-XX:SurvivorRatio设置Eden和S区的比值,有些垃圾回收期会对S0或者S1进行动态的调整。

之所以说大多数情况下新建的对象在新生代上分配,是因为有两种情况下java新创建的对象会直接到老年代,一种是大的数组对象,且对象中无外部引用的对象。另一种是通过启动参数上面进行设置-XX:PretenureSizeThreshold=1024(字节),意思是对象超过此大小,就直接分配到老年代上面。此外,并行垃圾回收期可以在运行期决定哪些对象可以直接创建在老年代。

老年代:
多次回收之后仍然存活的对象,大小是-Xms减去-Xmn

三、常见的启动参数解释
1、-Xms2g -Xmx2g -Xmn1g -XX:PermSize=64m -XX:MaxPermSize=128m
新生代分配1G,java heap最小2G,最大2G,持久带最小64M,最大128M

2、 -XX:SurvivorRatio=8
新生代中Eden和S0的比值是8,对应上面配置,Eden大小是10240.8M,S0和S1分别是10240.1M

3、-XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled
垃圾回收器使用CMS并发收集器,同时开启对旧生带的压缩,对于持久带区域也进行回收

4、-XX:CMSMaxAbortablePrecleanTime=5000 -XX:CMSInitiatingOccupancyFraction=80
对于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。promotion failed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。应对措施为:增大survivor space、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。对于这种状况,可通过设置-XX: CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。
使用cms作为垃圾回收,使用80%后开始CMS收集。

5、 -XX:+UseCompressedOops
64为操作系统开启指针压缩功能。

6、-XX:+DisableExplicitGC
关闭System.gc()

7、 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/java/logs
在JVM报OOM错误的时候自动dump内存文件,dump后的文件存储在/home/java/logs中,用于后续分析内存

8、 -verbose:gc -Xloggc:/home/java/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
在JVM中java程序运行过程中,打印gc的日志,文件存储在:/home/java/logs/gc.log 中,可以观察历史GC情况

9、 -Djava.awt.headless=true
Headless模式是系统的一种配置模式。在该模式下,系统缺少了显示设备、键盘或鼠标。
Headless模式虽然不是我们愿意见到的,但事实上我们却常常需要在该模式下工作,尤其是服务器端程序开发者。因为服务器(如提供Web服务的主机)往往可能缺少前述设备,但又需要使用他们提供的功能,生成相应的数据,以提供给客户端(如浏览器所在的配有相关的显示设备、键盘和鼠标的主机)。
一般是在程序开始激活headless模式,告诉程序,现在你要工作在Headless mode下,就不要指望硬件帮忙了,你得自力更生,依靠系统的计算能力模拟出这些特性来 。
在Java服务器程序需要进行部分图像处理功能时,建议将程序运行模式设置为headless,这样有助于服务器端有效控制程序运行状态和内存使用(可防止在处理大图片时发生内存溢出) 。

10、-Dsun.net.client.defaultConnectTimeout=10000
连接主机的超时时间(单位:毫秒)

11、 -Dsun.net.client.defaultReadTimeout=30000
从主机读取数据的超时时间

四、常见错误
1、旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:
java.lang.OutOfMemoryError: Java heap space

2、Permanet Generation中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:
java.lang.OutOfMemoryError: PermGen space
为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。

3、CMS GC时出现promotion failed和concurrent mode failure
在gc日志中含有这些信息,处理详见参数-XX:CMSMaxAbortablePrecleanTime=5000

4、线程请求的栈深度大于虚拟机所允许的最大深度
抛出StackOverflowError的错误

参考:
https://iamzhongyong.iteye.com/blog/1333100
https://www.cnblogs.com/qlqwjy/p/7929414.html
https://blog.csdn.net/u012610716/article/details/80898211
https://blog.csdn.net/lengyue309/article/details/80590119

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值