首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

JAVA使用for循环会重复调用list.size()吗?

最近有朋友讨论说for循环里不要用list.size(),这样会导致每次都调用一次list.size()接口会耗性能,建议我们在外面使用一个变量来存储这个list.size()的值再放到循环里面,真的是这样吗?我做了个小测试,代码如下: public class Test2 { public static void main(String[] args) { List list = new ArrayList<String>(); list.add("1"); list.add("2"); for (int i = 0; i < list.size(); i++) { System.out.println(i); } } } 这里将list.size()放在了for循环里,按朋友的说法,这里应该会调用多次。 接下来我查看了字节码发现,这里确实会调用多次list.size()方法,字节码如下: 具体字节码指令解析可查看:http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html 接着查看了ArrayList调用size()方法的源码是直接返回一个int 型的 size变量的,而这个size变量是每次新增和删除都会改变这个size的值 结论:经过网友们热情的探讨与更正,for循环里会多次调用list.size(),list.size()方法会直接返回一个声明在类中的size全局变量,虽然这个size会直接保存在堆中,但每次发生函数调用确实会发生压栈出栈的性能开销。

优秀的个人博客,低调大师

java中的四种引用(强,软,弱,虚)

一、强引用 概念:当对象不可达时,即可回收。 /** * 强引用。当强引用指针不存在时,对象将被回收 * 也可以理解为 ROOT 引用消失时,对象将被回收 */ public class StrongReference { /** * jvm在执行gc时 将回调该方法 * @throws Throwable */ @Override protected void finalize() throws Throwable { System.out.println("gc doing now !"); } public static void main(String[] args) { StrongReference strongReference = new StrongReference(); // 将引用指针移除 strongReference = null; // 手动调用gc System.gc(); } } 二、软引用 概念: 当内存空间不足时,将被回收。 /** * Xmx2oM 设置最大堆内存为20M * 软引用 会在内存空间不够时,进行 gc 操作。 从而 回收 软引用对象 */ public class MySoftReference { public static void main(String[] args) { SoftReference<byte[]> softReference = new SoftReference<byte[]>(new byte[1024*1024*10]); System.out.println("第一次gc前 : byte[]:" + softReference.get()); System.gc(); System.out.println("第一次执行gc后 : byte[]:" + softReference.get()); byte[] bytes = new byte[1024*1024*12]; System.out.println("内存不够后 : byte[]:" + softReference.get()); } } 上述代码的补充:源码中,我将虚拟机参数 -Xmx 设置为20M。 我先后 new 出来的 两个byte 数组均超过10M。 目标对象均会存放在老年代中。(按照 新生代 : 老年代 = 1:2.) 大概内存分布为。 老年代 20 * 2/3 约为13.3M。 年轻代 约为 20 * 1/3 约为 6.7M。其中 年轻代 eden:s0:s1 = 8:1:1 故 Eden 约为 5.3 M。So/S1 约为0.67M。如下图所示,基本跟计算出来的结果吻合。至于 多出来的部分,个人理解,jvm对计算出的堆大小自我调优勒。 基于对堆内存的分析。可以看出。 第一次 老年代 装入 10 M的 对象。 第二次 想要 装入 12M 对象。肯定装不下。 由于是 软引用。 jvm gc 时会将这部分内容先回收掉。 所以这里没有 出现OOM 的问题。 三、弱引用 (比较重要,面试常考题之一) 备注: ThreadLocal 里使用勒 弱引用。会产生内存泄露的问题。下篇博客,我会加以说明。 概念:jvm无视该引用。该对象可被弱引用对象获取到对象的实例。 当jvm执行gc时,将直接被回收。(提前条件:没有强引用存在)。 示例一: /** * 弱引用 虚拟机无视该引用。只要gc 一定会被回收(前提该对象没有被强引用) */ public class Test { public static void main(String[] args) { Teacher teacher = new Teacher(); WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher); System.out.println(weakReference.get()); // 若不将 teacher 置为null,则还存在一个强引用。不会被gc回收 //teacher = null; System.gc(); System.out.println(weakReference.get()); } 示例二: /** * User 对象持有 Teacher 对象的强引用。 * 当teacher 被置为null 时。 teacher 的强应用 随之消失。 * 而 User 对 Teacher 的强引用还在。 故 user.getTeacher() 并不是null * 所以 teacher 并不会被 gc 回收。 * * 当 user 也被置为null时。 user 对 teacher 的强引用也不存在勒。 * 此时 teacher 将会被gc回收 */ public class Test1 { public static void main(String[] args) { User user = new User(); Teacher teacher = new Teacher(); teacher.setName("zs"); user.setTeacher(teacher); WeakReference<Teacher> weakReference = new WeakReference<Teacher>(teacher); System.out.println(System.identityHashCode(weakReference.get())); System.out.println(System.identityHashCode(teacher)); System.out.println(System.identityHashCode(user.getTeacher())); teacher = null; System.out.println(user.getTeacher().getName()); // 当user 置为null 时, 对teacher 的强引用消失。 此时 teacher 将会被回收。 user = null; System.gc(); System.out.println(weakReference.get()); } } 示例三: public class People extends WeakReference<Teacher> { public People(Teacher referent) { super(referent); } } /** * People 继承自WeakReference<T> People也是一个虚拟引用对象。 * 所以teacher 被置为null时,强引用指针被清除。 * teacher 就会被gc回收。 */ public class Test2 { public static void main(String[] args) { Teacher teacher = new Teacher(); People people = new People(teacher); teacher = null; System.gc(); System.out.println(people.get()); } } 四、虚引用 概念:该引用很鸡肋。一个对象被虚引用所引用时。并不能获取到该实例的对象。只有当该对象被回收时,才会收到通过并存入队列中。基本上用于操作直接内存来使用的。 可用于对一些重要对象的gc的监听。或者监听gc的频率(不如打印gc日志来的简单直观)。 以下 jvm参数 -Xmx20M。 当然也可以更小,主要是为了看gc 的效果。 /** * 虚拟引用 * 比较鸡肋,虚拟引用的对象,并不能get()出来。 而是直接操作 操作系统内存的。 * 虚拟引用的目标对象,被回收后,会存入队列中 * 需要新启一个线程监听该队列中,是否有数据。有数据 则 回收掉直接内存。 */ public class MyPhantomReference { private static final List<Object> LIST = new LinkedList<Object>(); private static final ReferenceQueue<MyPhantomReference> QUEUE = new ReferenceQueue<MyPhantomReference>(); public static void main(String[] args) { PhantomReference<MyPhantomReference> phantomReference = new PhantomReference<MyPhantomReference>(new MyPhantomReference(),QUEUE); new Thread( () -> { while(true){ LIST.add(new byte[1024*1024]); try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); Thread.currentThread().interrupt(); } System.out.println(phantomReference.get()); } }).start(); new Thread( () -> { while(true){ Reference<? extends MyPhantomReference> poll = QUEUE.poll(); if(poll != null){ System.out.println("虚拟引用被jvm回收啦 ----" + poll); } } }).start(); try{ Thread.sleep(500); }catch(Exception e){ e.printStackTrace(); } } }

优秀的个人博客,低调大师

Java 如何用队列解决高并发访问接口的问题?

@RequestMapping(value = "test") @ResponseBody public void test(HttpServletRequest request){ //判断数据库是否有记录 if(!checkDbExist(request)){ //模拟数据库插入操作 dbInsert(request); } } 这个接口可能被高并发访问,所以就会出现如果数据重复发送就会出现数据库重复插入的问题,可以在方法上加synchronized关键字解决这个问题,如果是使用队列该怎么处理高并发的情况

优秀的个人博客,低调大师

Java 意义重大的 7 个性能指标

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 本文中,小编搜集了7个最有影响的衡量标注,让你可以不依赖日志文件来了解应用程序。现在,让我们看看这些性能指标,并了解如何查看并收集它们: 1.响应时间和吞吐量 根据应用程序的响应时间可以知道程序完成传输数据所用的时间。也可以从HTTP请求级别,或者成为数据库级别来看。对那些缓慢的查询你需要做一些优化来缩短时间。吞吐量是另一个角度衡量传输数据的指标,是指单位时间内系统处理的客户请求的数量。 我们可以使用APMs(例如New Relic或AppDynamics)来衡量这些指标。使用这些工具,你可以在主报告仪表板中将平均响应时间与昨天的甚至上周的直接进行对比。这有助于我们观察新的部署是否会影响到我们的应用程序。你可以看到网络传输的百分比,测量HTTP完成请求需要多长时间。 推荐工具: AppDynamicsNew RelicRuxit New Relic报告:Web传输百分比和吞吐量 2.平均负载 第二个应用广泛的指标是平均负载。我们习惯上会把平均负载分为这三步测量,分别是第5分钟、第15分钟和最后1分钟。要保证数量低于机器的内核数。一旦超过内核数,机器就会运行在压力状态下。(关注互联网架构师公众号回复“2T”,送你全套架构视频。) 除了简单测量CPU使用率,还需要关注每个内核的队列中有多少进程。在内核使用率都是100%的情况下,队列中只有1个任务和有6个任务有很大不同。因此,平均负载不能只考虑CPU使用率。 推荐工具: htop 3.错误率 大多数开发人员判断错误率是根据HTTP传输总失败百分比。但是他们忽略了一个更深层的东西:特定传输的错误率。这直接影响到您应用程序的运行状况。这可以显示出代码方法的错误以及错误或异常出现的次数。 但单纯的错误率数据对我们没有多大帮助。最重要的是我们要找到它们的根源并解决问题。随着Takipi的运行,我们要在日志文件中需找线索。你可以找到所有关于服务器状态的信息,包括堆栈跟踪、源代码和变量值。 推荐工具: Takipi 4.GC率和暂停时间 异常行为垃圾收集器应用程序的吞吐量和响应时间采取深潜的主要原因之一。了解GC暂停频率和持续时间的关键是分析GC日志文件。要分析它们,你需要收集GC日志和JVM参数。你要注意观察不同指标之间的数据是如何相互影响的。关注公众号互联网架构师,回复关键字2T,获取最新架构视频 推荐工具: jClarity CensumGCViewer 5.业务指标 应用程序的性能不完全取决于响应时间和错误率。业务指标也是一方面,例如收益、用户数。 推荐工具: GrafanaThe ELK stackDatadogLibrato 6.正常运行时间和服务运行状态 这一指标奠定了整个应用程序性能的基础。不仅可以当做一个提醒指标,也可以让你定义一段时间内的SKA。我们可以使用Pingdom的servlet功能进行运行状态检查。我们可以查到应用程序的所有传输,包括数据库和S3。 推荐工具: Pingdom 7.日志大小 日志有一个缺点,它是一直在增加的。当您的服务器启动塞满了垃圾,一切都慢下来。因此,我们需要密切的关注日志大小。 目前通常的解决办法是使用logstash划分使用日志,并将它们发送并存储在Splunk、ELK或其他的日志管理工具中。 推荐工具: SplunkSumo LogicLoggly 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/zhibo 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-07-26本文作者:王韵菲本文来自:“互联网架构师”,了解相关信息可以关注“互联网架构师”

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册