文档章节

java特殊场景下的内存相关的性能优化

乌龟壳
 乌龟壳
发布于 2017/05/09 00:08
字数 285
阅读 101
收藏 0

这几天都在外面跑,没时间上机调代码,晚上回来趁这机会研究下,结果如下:

bobguo@bobguo-PC:~/source/eetest$ java -version && javac hash.java && cat hash.java && time java -Xms2G -verbose:gc hash && time java -verbose:gc hash
Picked up _JAVA_OPTIONS:   -Dawt.useSystemAAFontSettings=gasp
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
Picked up _JAVA_OPTIONS:   -Dawt.useSystemAAFontSettings=gasp
import java.util.HashMap;
import java.util.Map;

public class hash {

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		String time;
		Map<String, String> map = new HashMap<>();
		for (int i = 0; i < 1000000; i++) {
			time = String.valueOf(System.currentTimeMillis());
			map.put(i + "_" + time, time);
		}
		System.out.println(System.currentTimeMillis() - start);
	}

}
Picked up _JAVA_OPTIONS:   -Dawt.useSystemAAFontSettings=gasp
690

real	0m0.806s
user	0m0.964s
sys	0m0.104s
Picked up _JAVA_OPTIONS:   -Dawt.useSystemAAFontSettings=gasp
[GC (Allocation Failure)  31744K->16720K(121856K), 0.0235111 secs]
[GC (Allocation Failure)  48464K->35592K(153600K), 0.0363266 secs]
[GC (Allocation Failure)  99080K->96188K(160256K), 0.0982848 secs]
[Full GC (Ergonomics)  96188K->95872K(278528K), 1.0974248 secs]
[GC (Allocation Failure)  159091K->145848K(295424K), 0.1148326 secs]
[Full GC (Ergonomics)  145848K->145669K(398336K), 0.9425082 secs]
2901

real	0m3.010s
user	0m9.548s
sys	0m0.200s

这个场景特殊在哪里呢?特殊在java擅长长期运行,所以针对这种从0开始剧烈使用内存,然后直接结束的的场景,默认参数并没有很好的优化导致的。

© 著作权归作者所有

共有 人打赏支持
下一篇: 支持Kotlin
乌龟壳

乌龟壳

粉丝 114
博文 22
码字总数 13436
作品 0
深圳
程序员
私信 提问
加载中

评论(10)

乌龟壳
乌龟壳

引用来自“orpherus”的评论

Java的gc给内存做了分代,100M的数据,它在年轻代里最多要占用200M(复制),然后到了老年代里还要占用100M,极端情况下,需要4倍的空间,因为设计上为了吞吐量,加上了内存池,用完的也不会立刻还给os,而是尽可能的多用内存,这点有点类似linux的缓存管理。

因为分代内部还分S0和S1,不光要从yong移动到old,在yong里面还有from和to,默认要移动15次之后,才会从yong移动到old,有些场合,会有大量需要15次移动的数据,严重降低内存管理效率,所以有时我们会调低MaxTenuringThreshold减少无效移动次数。

为吞吐和性能设计的VM,在资源占用量上是没有优势的,但是多消耗的资源能带来性能的提升。就好比豪车马力大油耗也更高,但是不适合烧不起油的人。JVM不是给那些2G以下内存的VPS用的,也不是给那些日PV连1000万都不到的微型站点用的。

引用来自“eechen”的评论

Java是对内存极度贪婪的魔鬼,Java对内存的控制完全过了头,简直就是想越过操作系统的内存管理自己搞一套,但却逃不掉内存膨胀和泄露的宿命.stop-the-world: GC => Full GC => GC overhead limit exceeded
nginx/php/js/java/mysql/postgres/oracle...我可以举出很多例子都是自己有一套内存管理体系的。自己管理内存太正常不过了。操作系统只负责在必要的时候给应用扩容就行了。
至于你说的内存泄露,代码写的有bug那是另说的。
eechen
eechen

引用来自“orpherus”的评论

Java的gc给内存做了分代,100M的数据,它在年轻代里最多要占用200M(复制),然后到了老年代里还要占用100M,极端情况下,需要4倍的空间,因为设计上为了吞吐量,加上了内存池,用完的也不会立刻还给os,而是尽可能的多用内存,这点有点类似linux的缓存管理。

因为分代内部还分S0和S1,不光要从yong移动到old,在yong里面还有from和to,默认要移动15次之后,才会从yong移动到old,有些场合,会有大量需要15次移动的数据,严重降低内存管理效率,所以有时我们会调低MaxTenuringThreshold减少无效移动次数。

为吞吐和性能设计的VM,在资源占用量上是没有优势的,但是多消耗的资源能带来性能的提升。就好比豪车马力大油耗也更高,但是不适合烧不起油的人。JVM不是给那些2G以下内存的VPS用的,也不是给那些日PV连1000万都不到的微型站点用的。

引用来自“乌龟壳”的评论

豪车的比喻很恰当

但是你的回答跑题了:-P
其实也不见得有多恰当,比亚迪走混合动力的路线,唐这台SUV就能轻松跑赢不少百万以内的所谓豪车.
我觉得底层用C实现的PHP7关联数组的【能耗比】相当好,相当适合普通使用者.
eechen
eechen

引用来自“orpherus”的评论

Java的gc给内存做了分代,100M的数据,它在年轻代里最多要占用200M(复制),然后到了老年代里还要占用100M,极端情况下,需要4倍的空间,因为设计上为了吞吐量,加上了内存池,用完的也不会立刻还给os,而是尽可能的多用内存,这点有点类似linux的缓存管理。

因为分代内部还分S0和S1,不光要从yong移动到old,在yong里面还有from和to,默认要移动15次之后,才会从yong移动到old,有些场合,会有大量需要15次移动的数据,严重降低内存管理效率,所以有时我们会调低MaxTenuringThreshold减少无效移动次数。

为吞吐和性能设计的VM,在资源占用量上是没有优势的,但是多消耗的资源能带来性能的提升。就好比豪车马力大油耗也更高,但是不适合烧不起油的人。JVM不是给那些2G以下内存的VPS用的,也不是给那些日PV连1000万都不到的微型站点用的。
Java是对内存极度贪婪的魔鬼,Java对内存的控制完全过了头,简直就是想越过操作系统的内存管理自己搞一套,但却逃不掉内存膨胀和泄露的宿命.stop-the-world: GC => Full GC => GC overhead limit exceeded
乌龟壳
乌龟壳

引用来自“orpherus”的评论

Java的gc给内存做了分代,100M的数据,它在年轻代里最多要占用200M(复制),然后到了老年代里还要占用100M,极端情况下,需要4倍的空间,因为设计上为了吞吐量,加上了内存池,用完的也不会立刻还给os,而是尽可能的多用内存,这点有点类似linux的缓存管理。

因为分代内部还分S0和S1,不光要从yong移动到old,在yong里面还有from和to,默认要移动15次之后,才会从yong移动到old,有些场合,会有大量需要15次移动的数据,严重降低内存管理效率,所以有时我们会调低MaxTenuringThreshold减少无效移动次数。

为吞吐和性能设计的VM,在资源占用量上是没有优势的,但是多消耗的资源能带来性能的提升。就好比豪车马力大油耗也更高,但是不适合烧不起油的人。JVM不是给那些2G以下内存的VPS用的,也不是给那些日PV连1000万都不到的微型站点用的。
豪车的比喻很恰当

但是你的回答跑题了:-P
orpherus
orpherus
Java的gc给内存做了分代,100M的数据,它在年轻代里最多要占用200M(复制),然后到了老年代里还要占用100M,极端情况下,需要4倍的空间,因为设计上为了吞吐量,加上了内存池,用完的也不会立刻还给os,而是尽可能的多用内存,这点有点类似linux的缓存管理。

因为分代内部还分S0和S1,不光要从yong移动到old,在yong里面还有from和to,默认要移动15次之后,才会从yong移动到old,有些场合,会有大量需要15次移动的数据,严重降低内存管理效率,所以有时我们会调低MaxTenuringThreshold减少无效移动次数。

为吞吐和性能设计的VM,在资源占用量上是没有优势的,但是多消耗的资源能带来性能的提升。就好比豪车马力大油耗也更高,但是不适合烧不起油的人。JVM不是给那些2G以下内存的VPS用的,也不是给那些日PV连1000万都不到的微型站点用的。
乌龟壳
乌龟壳

引用来自“eechen”的评论

https://static.oschina.net/uploads/space/2017/0507/114545_l2Gp_561214.png
同样逻辑,PHP7中用memory_get_peak_usage()可见PHP内存消耗在82MB左右.
显然Java的内存消耗要比PHP的82MB多得多.
java用了150M内存,这个确实比纯c写的要占空间,主要是字符串连接导致的很多中间对象要进行处理
还有String对象存储的是双字节的unicode,php里面都是单字节的。
但是,java有和c接近的性能加上有程度比较高的抽象,作为语言还是蛮好的。要知道hashmap是用java实现的。

晚上回去用个人电脑(同样环境)给你看看java最新的gc的威力。不用设置Xms也能达到比较好的性能。
乌龟壳
乌龟壳

引用来自“honey_fansy”的评论

改为Map<String, String> map = new HashMap<String, String>(1000000, 1F);试试
我觉得主要压力点是字符串拼接导致的过多新建String对象的垃圾收集问题。这也是我刻意没用StringBuilder甚至byte[]之类的去优化的原因。因为要和php比较,就要保持基本一致的概念。
honey_fansy
honey_fansy
改为Map<String, String> map = new HashMap<String, String>(1000000, 1F);试试
eechen
eechen
https://static.oschina.net/uploads/space/2017/0507/114545_l2Gp_561214.png
同样逻辑,PHP7中用memory_get_peak_usage()可见PHP内存消耗在82MB左右.
显然Java的内存消耗要比PHP的82MB多得多.
乌龟壳
乌龟壳
JVM性能优化, Part 5:Java的伸缩性

ImportNew注: JVM性能优化系列文章前4篇由ImportNew翻译(第一篇,第二篇,第三篇, 第四篇)。本文由新浪微博:吴杰 (@WildJay) 投稿至ImportNew。感谢吴杰! 如果你希望分享好的原创文章或...

梁杰_Jack
2014/10/30
0
0
05《Java核心技术》之三种字符串类有什么区别?

一、提出问题 今天,我们来聊聊日常使用的字符串,别看它似乎很简单,但其实字符串几乎在所有编程语言里都是个特殊的存在,因为不管是数量还是体积,字符串都是大多数应用中的重要组成。 今天...

飞鱼说编程
2018/09/24
0
0
Netty源码阅读入门实战(十)-性能优化

1 性能优化工具类 FastThreadLocal 传统的ThreadLocal ThreadLocal最常用的两个接口是set和get 最常见的应用场景为在线程上下文之间传递信息,使得用户不受复杂代码逻辑的影响 我们使用set的...

芥末无疆sss
2018/10/22
0
0
《成神之路-基础篇》JVM——JVM参数及调优(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 JVM参数及调优 JVM实用参数系列 成为Java GC专家(5)...

2018/05/05
0
0
2019年阿里Java面试必问:JVM与性能优化+Redis+设计模式+分布式

前言 一年之计在于春 金三银四已经要到来,2019的新的开始,作为一个开发人员,你是否面上了自己理想的公司,薪资达到心中理想的高度? 面试:如果不准备充分的面试,完全是浪费时间,更是对...

java知识分子
02/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

总结:线程间频繁切换为什么耗费资源?

因为线程切换的时候,CPU需要将此线程的所有执行状态保存起来,如线程编号,执行到的位置等,然后再去执行其它线程。

浮躁的码农
51分钟前
3
0
PHP版本高于5.5时,curl文件上传必须使用CurlFile对象

坑了我一天,之前@的方法各种上传不成功文件。都怀疑服务端有bug了。

叫我哀木涕
52分钟前
1
0
js算法总结

数列求和 等差数列求和 function sum(a0,d,n){//a0->首项,d->公差,n->项数//(首项+末项)*项数/2return (a0+(a0+d*n))*n/2;} 等比数列求和 function sum(a0,q,n){//a0->首项,q->公......

祖达
今天
3
0
小白?转型?毕业生?外行学习快速入行大数据开发指南

这篇文章中,本文将针对三种不同的、想要进入数据科学领域的人群,给出自己的经验,帮助他们迅速有效入行。 虽然没有适合每个人的万能解决方案,但这三类建议值得想转行的你一看。 第1类:新...

董黎明
今天
2
0
好文 | MySQL 索引B+树原理,以及建索引的几大原则

MySQL事实上使用不同的存储引擎也是有很大区别的,下面猿友们可以了解一下。 一、存储引擎的比较 注:上面提到的B树索引并没有指出是B-Tree和B+Tree索引,但是B-树和B+树的定义是有区别的。 ...

Java爬坑之路
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部