jvm一问一答
来源:互联网 发布:云烟 淘宝客 编辑:程序博客网 时间:2024/04/30 00:49
本文来自葛一鸣的jvm培训课程
写一个程序,让程序在运行之后,最终抛出由于Perm区溢出引起的OOM,给出运行的jdk版本,程序源码,运行参数,并说明你的基本思路
/** 1. jdk 1.7 2. @author bwx 3. @date 2017/11/16 4. question : 要求perm区溢出.Permanent 即 持久代(Permanent Generation),主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。 5. answers : 可以设置一个较小的MaxPermSize,但是必须要让jvm起来。然后载入类,实例化该类(**必须的**)。 6. jvm 参数 -server -XX:PermSize=1m -XX:MaxPermSize=4m */public class PermGenOutOfMemory { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> aClass = Class.forName("java.security.MessageDigest"); Object o = aClass.newInstance(); while (true) { } }}
问:What is a StackOverflowError, what causes it, and how should I deal with them?
答:这里写链接内容
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
解决方法:增加-xxs 参数大小,使函数调用终止。
问:写一个程序,尽量产生STW现象。给出代码和启动JVM参数。并附上GC的log日志,标出停顿的时间
答:
/** * @author bwx * @date 2017/11/17 * -Xmx64M 最大堆大小 -Xms64M 初始堆大小 -XX:+UseSerialGC 老年代垃圾回收算法 -XX:+PrintGCDetails -Xmn1m 年轻代大小 -XX:PretenureSizeThreshold=50 超过这个大小 直接进入老年代 -XX:MaxTenuringThreshold=1 多少次minor GC 进入老年代 * 垃圾回收算法:为让stw时间较长,增大年老代空间和选用serial old垃圾算法进行回收老年代 * jvm 参数 -Xmx64M -Xms64M -XX:+UseSerialGC -XX:+PrintGCDetails -Xmn1m -XX:PretenureSizeThreshold=50 -XX:MaxTenuringThreshold=1 * 输出GC log: * [GC[DefNew: 960K->63K(960K), 0.0007489 secs] 64438K->63775K(65472K), 0.0007749 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] time:29706 time:29806 [GC[DefNew: 959K->63K(960K), 0.0009279 secs] 64705K->64117K(65472K), 0.0009465 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] time:29907 time:30007 [GC[DefNew: 959K->63K(960K), 0.0008833 secs] 65034K->64413K(65472K), 0.0009006 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] time:30108 [GC[DefNew: 959K->959K(960K), 0.0000109 secs][Tenured: 64364K->64511K(64512K), 0.0519109 secs] 65324K->64647K(65472K), [Perm : 3236K->3236K(21248K)], 0.0519510 secs] [Times: user=0.05 sys=0.00, real=0.05 secs] [Full GC[Tenured: 64511K->64511K(64512K), 0.0437616 secs] 64665K->64654K(65472K), [Perm : 3236K->3236K(21248K)], 0.0437844 secs] [Times: user=0.05 sys=0.00, real=0.04 secs] [Full GC[Tenured: 64511K->64511K(64512K), 0.0446344 secs] 64654K->64654K(65472K), [Perm : 3236K->3236K(21248K)], 0.0446526 secs] [Times: user=0.05 sys=0.00, real=0.04 secs] =====准备清理=====:110622 time:30352 [Full GC[Tenured: 64511K->4409K(64512K), 0.0130335 secs] 64979K->4409K(65472K), [Perm : 3237K->3237K(21248K)], 0.0130716 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] time:30466 time:30566 [GC[DefNew: 896K->64K(960K), 0.0006367 secs] 5331K->4786K(65472K), 0.0006646 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] time:30667 [GC[DefNew: 960K->64K(960K), 0.0005735 secs] 5753K->5107K(65472K), 0.0005905 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] time:30767 time:30867 */public class StopTheWorld { private static final long starttime=System.currentTimeMillis(); private HashMap<Long,byte[]> map=new HashMap<Long,byte[]>(); public static void main(String[] args) throws InterruptedException { StopTheWorld stw=new StopTheWorld(); stw.start(); } private void start() throws InterruptedException { while(true){ try { for(int i=0;i<1024;i++){ map.put(System.nanoTime(), new byte[512]); } } catch (OutOfMemoryError e) { //在不可以分配的时候,进行清理部分空间,继续运行,这样会很快产生下一次垃圾回收 System.out.println("=====准备清理=====:"+map.size()); map.clear(); } long t=System.currentTimeMillis()-starttime; System.out.println("time:"+t); Thread.sleep(100); } }}
- 在我的机器上,minor gc(年轻代GC)会大概花费1毫秒的时间,平均每两次循环发生一次minor gc。
- full GC大概花费10毫秒。
问:是否有方法尽可能减少一次STW停顿时间?由此带来的弊端是什么?
答:减少一次STW停顿时间,我这里从三个方面回答,一个是垃圾算法选择,一个是程序使用堆设置,无用对象尽早释放
1、垃圾算法选择:现在都是多核cpu,可以采用并行和并发收集器,如果是响应时间优化的系统应用 ,则jdk6版本一般选择的垃圾回收算法是:XX:+UseConcMarkSweepGC,即cms收集器,这个收集器垃圾回收时间短,但是垃圾回收总时间变长,使的降低吞吐量,算法使用的是标记-清除,并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生”碎片”,使得运行效率降低.CMSFullGCsBeforeCompaction此值设置运行多少次GC以后对内存空间进行压缩,整理
2、程序使用堆设置:应该根据程序运行情况,通过Jvm垃圾回收分析,设置一个比较合适的堆大小,不能一意味的将堆设置过大,导致程序回收很大一块空间,所以会导致stw时间较长,
3、无用对象尽早释放:使用的对象,如果没有用,尽早设置null,尽量在年轻代将对象进行回收掉,可以减少full gc停顿时长
阅读全文
0 0
- jvm一问一答
- 一问一答
- 一问一答
- Moodle一问一答
- django一问一答
- sdnu1096一问一答
- 关于职业规划的一问一答
- Flex的一问一答
- 系统设计一问一答
- Flex的一问一答
- Flex的一问一答
- Flex的一问一答
- Flex的一问一答
- Flex的一问一答
- 【一问一答】错题库整理
- 一问一答,逼近解决办法
- 发放激活码 (一问一答)
- 一问一答闲谈redis
- Android Studio 打包多个APK对应不同API
- Python下修改pip安装源
- IntelliJ IDEA 使用
- Liunx 开机自启管理
- ubuntu16.04 +tensorflow1.4安装 + 运行问题解决
- jvm一问一答
- java
- CSS学习
- php curl_multi批量发送http请求
- mysql导入过大.sql文件报错处理
- 标准BT.656并行数据结构
- Linux/Centos 安装Redis遇到问题及解决
- C字符串操作总结
- Spring Boot 非web应用程序实例