首页 文章 精选 留言 我的

精选列表

搜索[性能优化],共10013篇文章
优秀的个人博客,低调大师

Java程序性能优化2

为'Vectors' 和 'Hashtables'定义初始大小 JVM为Vector扩充大小的时候需要重新创建一个更大的数组,将原原先数组中的内容复制过来,最后,原先的数组再被回收。可见Vector容量的扩大是一个颇费时间的事。通常,默认的10个元素大小是不够的。你最好能准确的估计你所需要的最佳大小。 例子:import java.util.Vector;public class DIC { public void addObjects (Object[] o) { // if length > 10, Vector needs to expand for (int i = 0; i< o.length;i++) { v.add(o); // capacity before it can add more elements. } } public Vector v = new Vector(); // no initialCapacity. } 更正:自己设定初始大小。 public Vector v = new Vector(20); public Hashtable hash = new Hashtable(10); 参考资料:Dov Bulka, "Java Performance and Scalability Volume 1: Server-Side Programming Techniques" Addison Wesley, ISBN: 0-201-70429-3 pp.55 – 57

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

Java程序性能优化3

在finally块中关闭Stream 程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。 例子:import java.io.*;public class CS { public static void main (String args[]) { CS cs = new CS (); cs.method (); } public void method () { try { FileInputStream fis = new FileInputStream ("CS.java"); int count = 0; while (fis.read () != -1) count++; System.out.println (count); fis.close (); } catch (FileNotFoundException e1) { } catch (IOException e2) { } } } 更正:在最后一个catch后添加一个finally块 参考资料:Peter Haggar: "Practical Java - Programming Language Guide".Addison Wesley, 2000, pp.77-79

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

Java程序性能优化4

使用'System.arraycopy ()'代替通过来循环复制数组 'System.arraycopy ()' 要比通过循环来复制数组快的多。 例子:public class IRB{ void method () { int[] array1 = new int [100]; for (int i = 0; i < array1.length; i++) { array1 [i] = i; } int[] array2 = new int [100]; for (int i = 0; i < array2.length; i++) { array2 [i] = array1 [i]; // Violation } } } 更正:public class IRB{ void method () { int[] array1 = new int [100]; for (int i = 0; i < array1.length; i++) { array1 [i] = i; } int[] array2 = new int [100]; System.arraycopy(array1, 0, array2, 0, 100); } }

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

Java程序性能优化6

避免不需要的instanceof操作 如果左边的对象的静态类型等于右边的,instanceof表达式返回永远为true。 例子: public class UISO { public UISO () {} }class Dog extends UISO { void method (Dog dog, UISO u) { Dog d = dog; if (d instanceof UISO) // always true. System.out.println("Dog is a UISO"); UISO uiso = u; if (uiso instanceof Object) // always true. System.out.println("uiso is an Object"); } } 更正: 删掉不需要的instanceof操作。 class Dog extends UISO { void method () { Dog d; System.out.println ("Dog is an UISO"); System.out.println ("UISO is an UISO"); } }

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

Java程序性能优化7

避免不需要的造型操作 所有的类都是直接或者间接继承自Object。同样,所有的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操作就是不必要的了。例子:class UNC { String _id = "UNC"; }class Dog extends UNC { void method () { Dog dog = new Dog (); UNC animal = (UNC)dog; // not necessary. Object o = (Object)dog; // not necessary. } } 更正: class Dog extends UNC { void method () { Dog dog = new Dog(); UNC animal = dog; Object o = dog; } }

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

Java程序性能优化9

使用移位操作来代替'a / b'操作 "/"是一个很“昂贵”的操作,使用移位操作将会更快更有效。 例子:public class SDIV { public static final int NUM = 16; public void calculate(int a) { int div = a / 4; // should be replaced with "a >> 2". int div2 = a / 8; // should be replaced with "a >> 3". int temp = a / 3; } } 更正:public class SDIV { public static final int NUM = 16; public void calculate(int a) { int div = a >> 2; int div2 = a >> 3; int temp = a / 3; // 不能转换成位移操作 } }

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

Android性能优化之UI实战

在Android应用开发过程中,屏幕上控件的布局代码和程序的逻辑代码通常是分开的。界面的布局代码是放在一个独立的xml文件中的,这个文件里面是树型组织的,控制着页面的布局。通常,在这个页面中会用到很多控件,控件会用到很多的资源。Android系统本身有很多的资源,包括各种各样的字符串、图片、动画、样式和布局等等,这些都可以在应用程序中直接使用。这样做的好处很多,既可以减少内存的使用,又可以减少部分工作量,也可以缩减程序安装包的大小。 原文博客地址:http://www.apkbus.com/blog-919651-76902.html []()1)利用系统定义的id 在xml文件中引用系统的id,只需要加上“@android:”前缀即可。如果是在Java代码中使用系统资源,和使用自己的资源基本上是一样的。不同的是,需要使用android.R类来使用系统的资源,而不是使用应用程序指定的R类。这里如果要获取ListView可以使用android.R.id.list来获取。 <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent"/> []()2)利用系统的图片资源 Android中没有公开的资源,在xml中直接引用会报错。除了去找到对应资源并拷贝到我们自己的应用目录下使用以外,我们还可以将引用“@android”改成“@*android”解决。比如上面引用的附件图标,可以修改成下面的代码。 android:icon="@*android:drawable/ic_menu_attachment" 修改后,再次Build工程,就不会报错了。 []()3)利用系统的字符串资源 如果使用系统的字符串,默认就已经支持多语言环境了。如上述代码,直接使用了@android:string/yes和@android:string/no,在简体中文环境下会显示“确定”和“取消”,在英文环境下会显示“OK”和“Cancel”。 []()4)利用系统的Style android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" /> 其中android:textAppearance="?android:attr/textAppearanceMedium"就是使用系统的style。需要注意的是,使用系统的style,需要在想要使用的资源前面加“?android:”作为前缀,而不是“@android:”。 []()5)利用系统的颜色定义 []()6)提取共同的组件,通过include引入 <include layout="@layout/navigator_bar" /> 一般情况下,在项目的初期就能够大致确定整体UI的风格。所以早期的时候就可以做一些规划,将通用的模块先写出来。 下面是可能可以抽出的共用的布局: 1)背景。有的应用在不同的界面里会用到统一的背景。后期可能会经常修改默认背景,所以可以将背景做成一个通用模块。 2)头部的标题栏。如果应用有统一的头部标题栏,就可以抽取出来。 3)底部的导航栏。如果应用有导航栏,而且大部分的Activity的底部导航栏是相同的,就可以将导航栏写成一个通用模块。 4)ListView。大部分应用都会用到ListView展示多条数据。项目后期可能会经常调整ListView的风格,所以将ListView作为一个通用的模块比较好。 []()7)延迟加载隐藏的View 有时候,我们的页面中可能会包含一些布局,这些布局默认是隐藏的,当用户触发了一定的操作之后,隐藏的布局才会显示出来。比如,我们有一个Activity用来显示好友的列表,当用户点击Menu中的“导入”以后,在当前的Activity中才会显示出一个导入好友的布局界面。从需求的角度来说,这个导入功能,一般情况下用户是不使用的。即大部分时候,导入好友的布局都不会显示出来。这个时候,就可以使用延迟加载的功能。 ViewStub是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件。当ViewStub被设置为可见,或者调用inflate()函数时,才会真的去加载这个布局资源文件。该ViewStub在加载视图时会在父容器中替换它本身。因此,ViewStub会一直存在于视图中,直到调用setVisibility(int)或者inflate()为止。ViewStub的布局参数会随着加载的视图数一同被添加到ViewStub父容器。同样,也可以通过使用inflated Id属性来定义或重命名要加载的视图对象的Id值。 <ViewStub android:id="@+id/stub_import" android:inflatedId="@+id/panel_import" android:layout="@layout/progress_overlay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" /> 通过“stub_import”这个id可以找到被定义的ViewStub对象。加载布局资源文件“progress_overlay”后,ViewStub对象从其父容器中移除。可以通过“panel_import”这个id找到由布局资源“progress_overlay”创建的View。 ((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE); // 或者 View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

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

Android性能优化之内存泄漏

综述 内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存。那么在Android中,当一个对象持有Activity的引用,如果该对象不能被系统回收,那么当这个Activity不再使用时,这个Activity也不会被系统回收,那这么以来便出现了内存泄漏的情况。在应用中内出现一次两次的内存泄漏获取不会出现什么影响,但是在应用长时间使用以后,若是存在大量的Activity无法被GC回收的话,最终会导致OOM的出现。那么我们在这就来分析一下导致内存泄漏的常见因素并且如何去检测内存泄漏。 导致内存泄漏的常见因素 情景一:静态Activity和View 静态变量Activity和View会导致内存泄漏,在下面这段代码中对Activity的Context和TextView设置为静态对象,从而产生内存泄漏。 importandroid.content.Context; importandroid.support.v7.app.AppCompatActivity; importandroid.os.Bundle; importandroid.widget.TextView; publicclassMainActivityextendsAppCompatActivity{ privatestaticContextcontext; privatestaticTextViewtextView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context=this; textView=newTextView(this); } } 情景二:Thread,匿名类,内部类 在下面这段代码中存在一个非静态的匿名类对象Thread,会隐式持有一个外部类的引用LeakActivity,从而导致内存泄漏。同理,若是这个Thread作为LeakActivity的内部类而不是匿名内部类,他同样会持有外部类的引用而导致内存泄漏。在这里只需要将为Thread匿名类定义成静态的内部类即可(静态的内部类不会持有外部类的一个隐式引用)。 publicclassLeakActivityextendsAppCompatActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); leakFun(); } privatevoidleakFun(){ newThread(newRunnable(){ @Override publicvoidrun(){ try{ Thread.sleep(Integer.MAX_VALUE); }catch(InterruptedExceptione){ e.printStackTrace(); } } }); } } 情景三:动画 在属性动画中有一类无限循环动画,如果在Activity中播放这类动画并且在onDestroy中去停止动画,那么这个动画将会一直播放下去,这时候Activity会被View所持有,从而导致Activity无法被释放。解决此类问题则是需要早Activity中onDestroy去去调用objectAnimator.cancel()来停止动画。 publicclassLeakActivityextendsAppCompatActivity{ privateTextViewtextView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); textView=(TextView)findViewById(R.id.text_view); ObjectAnimatorobjectAnimator=ObjectAnimator.ofFloat(textView,"rotation",0,360); objectAnimator.setRepeatCount(ValueAnimator.INFINITE); objectAnimator.start(); } } 情景四:Handler 对于Handler的内存泄漏在(Android的消息机制——Handler的工作过程)[http://blog.csdn.net/ljd2038/article/details/50889754]这篇文章中已经详细介绍,就不在赘述。 情景五:第三方库使用不当 对于EventBus,RxJava等一些第三开源框架的使用,若是在Activity销毁之前没有进行解除订阅将会导致内存泄漏。 使用MAT检测内存泄漏 对于常见的内存泄露进行介绍完以后,在这里再看一下使用MAT(Memory Analysis Tool)来检测内存泄露。MAT的下载地址为:http://www.eclipse.org/mat/downloads.php。 下面来看一段会导致内存泄露的错误代码。 publicclassLeakActivityextendsAppCompatActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_leak); EventBus.getDefault().register(this); } @Subscribe publicvoidsubscriber(Strings){ } } 在上面这段代码中有会导致内存泄漏,原因是EventBus没有解除注册。下面就以这段代码为例来看一下如何分析内存泄漏。 打开AndroidStudio中的Monitors可以看到如下界面。 在这里可以看到在应用刚启动的时候,所占用的内存为15M,然后我们现在开始操作APP,反复进入退出LeakActicity。点击上如中的GC按钮。这时候我们在看一下内存使用情况。 在这里我们可以看到,内存一直在持续增加,已经达到33M,并且无法被GC所回收。所以我们可以判断,这时候必然出现内存泄漏的情形。那么现在再点击Dump Java Heap按钮,在captures窗口看到生成得hprof文件。但这时候所生成的hprof文件不是标准格式的,我们需要通过SDK所提供的工具hprof-conv进行转化,该工具在SDK的platform-tools目录下。执行命令如下: hprof-convXXX.hprofconverted-dump.hprof 当然在AndroidStudio中可以省去这一步,可以直接导出标准格式的hprof文件。 这时候可以通过MAT工具来打开导出的hprof文件。打开界面如下图所示: 在MAT中我们最常用的就是Histogram和Dominator Tree,他们分别对应上图中的A和B按钮。Histogram可以看出内存中不同类型的buffer的数量和占用内存的大小,而Dominator Tree则是把内存中的对象按照从大到小的顺序进行排序,并且可以分析对象之间的引用关系。在这里再来介绍一下MAT中两个符号的含义。 ShallowHeap:对象自身占用的内存大小,不包括他引用的对象 RetainedHeap:对象自身占用的内存大小并且加上它直接或者间接引用对象的大小 Histogram 由于在Android中一般内存泄漏大多出现在Acivity中,这时候可以点击Histogram按钮,并搜索Activity。 在这里可以看出LeakActivity存在69个对象,基本上可以断定存在内存泄漏的情形,这时候便可以通过查看GC对象的引用链来进行分析。点击鼠标右键选择Merge Shortest paths to GC Roots并选择exclude weak/soft references来排除弱引用和软引用。 在排除软引用和弱引用以后如下图所示: 在这里可以看出由于EventBus导致的LeakActivity内存泄漏。 在Histogram中还可以查看一个对象包含了那些对象的引用。例如,现在要查看LeakActivity所包含的引用,可以点击鼠标右键,选择list objects中的with incoming reference。而with outcoming reference表示选中对象持有那些对象的引用。 Dominator Tree 现在我们点击这时候可以点击Dominator Tree按钮,并搜索Activity。可以看到如下图所示: 在这里可以看到存在大量的LeakActivity。然后点击鼠标右键选择Path To GC Roots->exclude weak/soft references来排除弱引用和软引用。 exclude weak/soft references来排除弱引用和软引用" title="点击鼠标右键选择Path To GC Roots->exclude weak/soft references来排除弱引用和软引用" style="border:none;" data-original="http://s3.51cto.com/wyfs02/M00/8B/E2/wKioL1hbrCjTNwxTAAJ1gvALA-c226.jpg"> 之后可以看到如下结果,依然是EventBus导致的内存泄漏: 总结 内存泄漏往往被我们所忽略,但是当大量的内存泄漏以后导致OOM。它所造成的影响也是不容小觑的。当然除了上述内存泄漏的分析以为我们还可以通过LeakCanary来分析内存泄漏。对于LeakCanary的使用在这里就不在进行详细介绍。 本文作者:佚名 来源:51CTO

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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文件系统,支持十年生命周期更新。

用户登录
用户注册