ArrayList插入1000w条数据之后,我怀疑了jvm...

简介: "狼哥,我发现新大陆了,等会发你代码""咋了,这么激动""等会..."List<Integer> list0 = new ArrayList<Integer>();long start0 = System.currentTimeMillis();for (int i = 0; i < 10000000; i++){list0.add(i);}System.out.println(System.currentTimeMillis() - start0);long start1 = System.currentTimeMillis();List<Inte

"狼哥,我发现新大陆了,等会发你代码"

"咋了,这么激动"

"等会..."

List list0 = new ArrayList();

long start0 = System.currentTimeMillis();

for (int i = 0; i < 10000000; i++)

{

list0.add(i);

}

System.out.println(System.currentTimeMillis() - start0);

long start1 = System.currentTimeMillis();

List list1 = new ArrayList();

for (int i = 10000000; i < 20000000; i++)

{

list1.add(i);

}

System.out.println(System.currentTimeMillis() - start1);

"我在一个ArrayList中连续插入1千万条数据,结果耗时不一样,分别是

2346

797

没搞明白"

我看了一眼,就知道这小伙底盘不稳。

"你加个 -XX:+PrintGCDetails -XX:+PrintGCDateStamps,看下第一次是不是有Full GC"

"明白,我再试试看"

几分钟后...

"狼哥,第一次Full GC果然耗时了1.87s,那我把堆调大看看,避免Full GC"

几分钟后...

"这次没有GC了,但是每次运行,前一个都比后一个耗时多点,这是怎么回事?"

"你试试放在不同线程中运行?"

"好"

又几分钟后...

2019-09-28T09:49:07.519-0800: [GC (Allocation Failure) [PSYoungGen: 54888K->10738K(76288K)] 54888K->36180K(251392K), 0.0520111 secs] [Times: user=0.24 sys=0.03, real=0.06 secs]

2019-09-28T09:49:07.590-0800: [GC (Allocation Failure) [PSYounGen: 74092K->10736K(141824K)] 99534K->80803K(316928K), 0.0693607 secs] [Times: user=0.39 sys=0.03, real=0.06 secs]

2019-09-28T09:49:07.751-0800: [GC (Allocation Failure)[PSYoungGen: 141808K->10736K(141824K)] 211875K->188026K(320512K), 0.1829926 secs] [Times: user=1.02 sys=0.10, real=0.18 secs]

2019-09-28T09:49:07.934-0800: [Full GC (Ergonomics) [PSYoungGen:10736K->0K(141824K)] [ParOldGen: 177290K->171620K(402432K)] 188026K->171620K(544256K), [Metaspace:3062K->3062K(1056768K)], 1.8672996 secs][Times: user=5.96 sys=0.03, real=1.87 secs]

2365

2019-09-28T09:49:09.832-0800: [GC (Allocation Failure) [PSYoungGen: 129254K->10738K(196608K)] 300875K->282609K(599040K), 0.1039307 secs] [Times: user=0.74 sys=0.07, real=0.10 secs]

2019-09-28T09:49:09.936-0800: [Full GC (Ergonomics) [PSYoungGen: 10738K->0K(196608K)] [ParOldGen: 271871K->36047K(372736K)] 282609K->36047K(569344K), [Metaspace: 3067K->3067K(1056768K)], 0.4510440 secs] [Times: user=1.82 sys=0.01, real=0.45 secs]

2019-09-28T09:49:10.440-0800: [GC (Allocation Failure) [PSYoungGen: 185856K->10752K(264704K)] 221903K->171359K(637440K), 0.1292143 secs] [Times: user=0.97 sys=0.01, real=0.12 secs]

"狼哥,第一次Full GC果

"在不同线程中执行,两者耗时几乎一致,这是为什么?"

"你知道OSR吗?"

"不知道."

"那我跟你大概讲讲."

OSR(On-Stack Replacement ),是一种在运行时替换正在运行的手机号码卖号函数/方法的栈帧的技术。

在现代的主流JVM中,都具备了多层编译的能力,一开始以-解-释的方式进行执行,这种性能相对来说(和c++比)会慢一点,但是一旦发现某一个函数执行很频繁的时候,就会采用JIT编译,提高函数执行性能(大部分比c++还快)。

但是,如果以函数为单位进行JIT编译,那么就无法应对main函数中包含循环体的情况,这个时候,OSR就派上了用场。

与其编译整个方法,我们可以在发现某个方法里有循环很热的时候,选择只编译方法里的某个循环,当循环体执行到 i = 5000 的时候,循环计数器达到了触发OSR编译的阈值,等编译完成之后,就可以执行编译后生成的代码。所以在上面例子中,当我们第二次执行循环体的时候,已经在执行OSR编译后的代码,那么在性能上会比前一次会快那么一点点。

目录
相关文章
|
6月前
|
消息中间件 存储 Java
jvm性能调优实战 - 47超大数据量处理系统是如何OOM的
jvm性能调优实战 - 47超大数据量处理系统是如何OOM的
75 0
|
1月前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
61 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
27天前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
26 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
5月前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
63 2
|
6月前
|
存储 算法 Java
JVM 数据区域
JVM 数据区域
|
6月前
|
存储 Java 编译器
【JVM】运行时数据区域
【JVM】运行时数据区域
43 0
|
6月前
|
存储 算法 Java
JVM-01Java内存区域与内存溢出异常(上)【运行时区域数据】
JVM-01Java内存区域与内存溢出异常(上)【运行时区域数据】
53 0
|
6月前
|
存储 算法 Java
[JVM] 美团二面,说一下JVM数据区域
[JVM] 美团二面,说一下JVM数据区域
|
Arthas 消息中间件 监控
JVM第五讲:纵横数据如何应对洪峰推送
JVM第五讲:纵横数据如何应对洪峰推送
JVM第五讲:纵横数据如何应对洪峰推送
|
存储 Java 数据管理
【面试题精讲】JVM-运行时数据区-帧数据
【面试题精讲】JVM-运行时数据区-帧数据