解析高并发大对象处理
常年浸润在互联网高并发中的同学,在写代码时会有一些约定俗成的规则:宁可将请求拆分成10个1秒的,也不去做一个耗时5秒的请求;宁可将对象拆成1000个10KB的,也尽量避免生成一个1MB的对象。 为什么?这是对于“大”的恐惧。 “大对象”,是一个泛化的概念,它可能存放在JVM中,也可能正在网络上传输,也可能存在于数据库中。 为什么大对象会影响我们的应用性能呢?有三点原因。 大对象占用的资源多,垃圾回收器要花一部分精力去对它进行回收; 大对象在不同的设备之间交换,会耗费网络流量,以及昂贵的I/O; 对大对象的解析和处理操作是耗时的,对象职责不聚焦,就会承担额外的性能开销。 接下来,xjjdog将从数据的结构纬度和时间维度,来逐步看一下一些把对象变小,把操作聚焦的策略。 1. String的substring方法 我们都知道,String在Java中是不可变的,如果你改动了其中的内容,它就会生成一个新的字符串。 如果我们想要用到字符串中的一部分数据,就可以使用substring方法。 如图所示,当我们需要一个子字符串的时候。substring生成了一个新的字符串,这个字符串通过构造函数的Arrays.copyOfRange函数进行构造。 这个函数在JDK7之后是没有问题的,但在JDK6中,却有着内存泄漏的风险。我们可以学习一下这个案例,来看一下大对象复用可能会产生的问题。 这是我从JDK官方的一张截图。可以看到,它在创建子字符串的时候,并不只拷贝所需要的对象,而是把整个value引用了起来。如果原字符串比较大,即使不再使用,内存也不会释放。 比如,一篇文章内容可能有几MB,我们仅仅需要其中的摘要信息,也不得维持着整个的大对象。
这对我们的借鉴意义是。如果你创建了比较大的对象,并基于这个对象生成了一些其他的信息。这个时候,一定要记得去掉和这个大对象的引用关系。 (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |