什么是java的内存泄漏

  categories:资料  author:

来源:互联网

Java最显著的优势之一就是它的内存管理机制。你只需简单创建对象,然后Java垃圾回收机制便会小心的分配和释放内存。然而,事实并非如此简单,因为在Java应用程序中经常发生内存泄漏。

本教程说明了什么是内存泄漏,为什么会发生,以及如何防止它们。

1.什么是内存泄漏?

内存泄漏的定义: 对象不再被应用程序使用,但是垃圾回收器却不能移除它们,因为它们正在被引用。

要理解这个定义,我们需要理解对象在内存中的状态,下图说明了哪些是未被使用的以及哪些是未被引用的。

从图中可以看到被引用的对象和未被引用的对象。未被引用的对象将会被垃圾回收器回收,而被引用对象则不会被回收。未被引用的对象理所当然是未被使用的,因为没有其他的对象引用它。然而,未被使用的对象并不一定是未被引用的,其中一些是被引用的。这就是内存泄漏的起因。

2.为什么会发生内存泄漏?

让我们来看看下面这个例子,看看为什么内存泄漏会发生。在如下例子中,对象A引用了对象B。A的生命周期(t1-t4)要比B的生命周期(t2- t3)长很多。当B不再用于应用中时,A仍然持有对它的引用。在这种方式下,垃圾回收器就不能将B从内存中移除。这将可能导致出现内存不足的问题,因为如 果A对更多的对象做同样的事情,那么内存中将会有很多无法被回收的对象,这将极度耗费内存空间。

也有可能B持有大量对其他对象的引用,这些被B引用的对象也不能够被回收。所有这些未被使用的对象将会耗费宝贵的内存空间。

3.如何阻止内存泄漏?

以下是一些阻止内存泄漏的快速动手技巧。

(1)注意集合类,例如HashMap,ArrayList,等等。因为它们是内存泄漏经常发生的地方。当它们被声明为静态时,它们的生命周期就同应用程序的生命周期一般长。

(2)注意事件监听器和回调,如果一个监听器已经注册,但是当这个类不再被使用时却未被注销,就会发生内存泄漏。

(3)”如果一个类管理它自己的内存,程序员应该对内存泄漏保持警惕。”[1] 很多时候当一个对象的成员变量指向其他对象时,不再使用时需要被置为null。

4.一个小测验:为什么在JDK6中substring()方法会引起内存泄漏?

为了回答这个问题,您可能需要阅读JDK6和7中的substring() 阅读全文

减少GC开销的5个编码技巧

  categories:资料  author:

来源:互联网

在 这篇文章中,我们来了解一下让代码变得高效的五种技巧,这些技巧可以使我们的垃圾收集器(GC)在分配内存以及释放内存上面,占用更少的CPU时间,减少 GC的开销。当内存被回收的时候,GC处理很长时间经常会导致我们的代码中断(又叫做”stop the world”)。

背景

GC用来处理大量的短期的对象的分配(试想打开一个web页面,一旦页面被加载之后,被分配内存的大部分对象都会被废弃)。

GC使用一个被称作”新生代”堆空间来完成这件事情。”新生代”是用来存放新建对象的堆内存。每一个对象都有一个”age”(存储在对象的头信息 中),用来定义存放很多没有被回收的垃圾集合。一旦一个确定的”age”到达,对象就会被复制到堆中的另一块空间,这个空间被称作”幸存者空间”或者”老 年代空间”。(译者注:实际上幸存者空间位于新生代空间中,原文有误,不过这里暂时按照原文来翻译,更详细的内容请点击成为JavaGC专家Part I – 深入浅出Java垃圾回收机制)

虽然这样很有效,但是还是有很大代价的。减少临时分配的数量确实可以帮助我们增加吞吐量,尤其是在大规模数据的环境下,或者资源有限制的app中。

下面的五种代码方式可以更加有效的利用内存,并且不需要花费很多的时间,也不会降低代码可读性。

1、避免隐式的String字符串

String字符串是我们管理的每一个数据结构中不可分割的一部分。它们在被分配好了之后不可以被修改。比如”+”操作就会分配一个链接两个字符串的新的字符串。更糟糕的是,这里分配了一个隐式的StringBuilder对象来链接两个String字符串。

例如:

a = a + b;// a and b are Strings

编译器在背后就会生成这样的一段儿代码:

StringBuilder temp =newStringBuilder(a).

temp.append(b);

a = temp.toString();// 一个新的 String 对象被分配… 阅读全文

Java 8简明教程

  categories:资料  author:

来源:互联网
“Java并没有没落,人们很快就会发现这一点”

欢迎阅读我编写的Java 8介绍。本教程将带领你一步一步地认识这门语言的新特性。通过简单明了的代码示例,你将会学习到如何使用默认接口方法,Lambda表达式,方法引用和重复注解。看完这篇教程后,你还将对最新推出的 API有一定的了解,例如:流控制,函数式接口,map扩展和新的时间日期API等等。

允许在接口中有默认方法实现
Java 8 允许我们使用default关键字,为接口声明添加非抽象的方法实现。这个特性又被称为扩展方法。下面是我们的第一个例子:
package cn.iigrowing.java8;

public interface Formula {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
在接口Formula中,除了抽象方法caculate以外,还定义了一个默认方法sqrt。Formula的实现类只需要实现抽象方法caculate就可以了。默认方法sqrt可以直接使用。
package cn.iigrowing.java8;

public class TestFormula {
public … 阅读全文

JDK6和JDK7中的substring()方法

  categories:资料  author:

来源:互联网

 

substring(int beginIndex, int endIndex)在JDK6与JDK7中的实现方式不一样,理解他们的差异有助于更好的使用它们。为了简单起见,下面所说的substring()指的 就是substring(int beginIndex, int endIndex)方法。

1.substring()是做什么的?

substring(int beginIndex ,int endIndex)方法返回一个子字符串,返回的是从原字符串的beginIndex到endIndex-1之间的内容。

String x =”abcdef”;

x = x.substring(1,3);

System.out.println(x);

输出:

“bc”

2.当substring()被调用的时候,内部发生什么事?

你或许会认为由于x是不可变的对象,当x被x.substring(1,3)返回的结果赋值后,它将指向一个全新的字符串如下图:

然而,这个图并不完全正确,或者说并没有完全表示出java 堆中真正发生的事情。那么当调用substring()的时候到底发生的了什么事呢?JDK 6与JDK7的substring方法实现有什么不一样呢?

3.JDK6中的substring()

java中字符串是通过字符数组来支持实现的,在JDK6中,String类包含3个域,char[] value、int offset、int count。分别用于存储真实的字符数组、数组的偏移量,以及String所包含的字符的个数。

当substring()方法被调用的时候,它会创建一个新的字符串对象,但是这个字符串的值在java 堆中仍然指向的是同一个数组,这两个字符串的不同在于他们的count和offset的值。

下面是jdk6中的原代码,是简化后只包含用来说明这个问题的关键代码:

//JDK 6

String(intoffset,intcount,charvalue[]) 阅读全文

使用Java处理大文件

  categories:资料  author:

来源:互联网

我最近要处理一套存储历史实时数据的大文件fx market data,我很快便意识到,使用传统的InputStream不能够将它们读取到内存,因为每一个文件都超过了4G。甚至编辑器都不能够打开这些文件。

在这种特殊情况下,我可以写一个简单的bash脚本将这些文件分成更小的文件块,然后再读取它。但是我不想这样做,因为二进制格式会使这个方法失效。

处理这个问题的方式通常就是使用内存映射文件递增地处理区域的数据。关于内存映射文件的一个好处就是它们不会使用虚拟内存和换页空间,因为它们是从磁盘上的文件返回来的数据。

很好,让我们来看一看这些文件和额外的一些数据。似乎它们使用逗号分隔的字段包含ASCII文本行。

格式:[currency-pair],[timestamp],[bid-price],[ask-price]

例子:EUR/USD,20120102 00:01:30.420,1.29451,1.2949

我可以为这种格式去写一个程序,但是,读取文件和解析文件是无关的概念。让我们退一步来想一个通用的设计,当在将来面临相似的问题时这个设计可以被重复利用。

这个问题可以归结为递增地解码一个已经在无限长的数组中被编码的记录,并且没有耗尽内存。实际上,以逗号分割的示例格式编码与通常的解决方案是不相关的。所以,很明显需要一个解码器来处理不同的格式。

再来看,知道整个文件处理完成,每一条记录都不能被解析并保存在内存中,所以我们需要一种方式来转移记录,在它们成为垃圾被回收之前可以被写到其他地方,例如磁盘或者网络。

迭代器是处理这个需求的很好的抽象,因为它们就像游标一样,可以正确的指向某个位置。每一次迭代都可以转发文件指针,并且可以让我们使用数据做其他的事情。

首先来写一个Decoder 接口,递增地把对象从MappedByteBuffer中解码,如果buffer中没有对象,则返回null。

publicinterfaceDecoder<T> {

publicT decode(ByteBuffer buffer);

}

然后让FileReader 实现Iterable接口。每一个迭代器将会处理下一个4096字节的数据,并使用Decoder把它们解码成一个对象的List集合。注 意,FileReader 接收文件(files)的list对象,这样是很好的,因为它可以遍历数据,并且不需要考虑聚合的问题。顺便说一下,4096个字节块对于大文件来说是非 常小的。

publicclassFileReaderimplementsIterable<List<T>> {

privatestaticfinallongCHUNK_SIZE =4096;

privatefinalDecoder<T> decoder;

privateIterator<File> files;

privateFileReader(Decoder<T> … 阅读全文

Android–UI之ScrollView实例

  categories:android  tags:  author:

ScrollView和HorizontalScrollView是Android当中比较常用的两个布局容器,从字面意义上 来看也是非常的简单的,ScrollView就是一个可以滚动的View,这个滚动的方向是垂直方向的,而HorizontalScrollView则是 一个水平方向的可以滚动的View。本篇随笔可能描述性的知识比较少,最主要还是通过代码来看看如何使用这两个View。

一、ScrollView的简单介绍

首先来看看ScrollView和HorizontalScrollView这两个View的定义。ScrollView和 HorizontalScrollView都是一个布局容器,里面可以放入child View控件,我们通过其继承关系看到,ScrollView和HorizontalScrollView这两个类是ViewGroup的一个间接子类。

java.lang.Object   ↳    android.view.View        ↳    android.view.ViewGroup             ↳    android.widget.FrameLayout                  ↳    android.widget.ScrollView

java.lang.Object   ↳    android.view.View        ↳    android.view.ViewGroup             ↳    android.widget.FrameLayout                  ↳    android.widget.HorizontalScrollView

因为ScrollView和HorizontalScrollView只是两种滚动方向不同的View而已,其他方面都基本相同,所以下面只单单以ScrollView来讲解。

通过使用ScrollView,我们可以滚动其里面的子View控件,这样就允许我们控件的高度可以大于我们实际屏幕的尺寸高度。 ScrollView是一个FrameLayout,至于什么是FrameLayout,简单的来说,FrameLayout通常被用来设计成在屏幕上占 用一块地方并且里面只有一个Item,我们常用到的例如DatePicker、TimePicker这些控件都是属于FrameLayout布局的。因此 在ScrollView当中,也通常只包含一个子元素,并且这个子元素也是一个布局文件,这样我们才能在这个布局文件里面添加我们想要的任何子控件,从而 实现滚动的效果。

对于ScrollView来说,因为其是垂直方向上的滚动布局,因此通常我们给其添加一个LinearLayout的子元素,并且设置 orientation为vertical(垂直方向的)。下面我们通过一个小例子来看看如何使用我们的ScrollView来展示多张图片,并且实现图 片的垂直方向的滚动。

首先我们定义一个ScrollView,因为ScrollView也是一个ViewGroup,所以我们可以直接使用ScrollView作为我们的xml文件的根元素:

通过官方文档的继承关系可以看出,它继承自FrameLayout,所以它是一种特殊类型的FrameLayout,因为它可以使用用户滚动显示一个占据 的空间大于物理显示的视图列表。值得注意的是,ScrollView只能包含一个子视图或视图组,在实际项目中,通常包含的是一个垂直的 LinearLayout。

值得注意的是,ScrollView不能和ListView一起使用,因为ListView已经对垂直方向的滚动做了处理,它会迫使如果 ListView的内容大于物理视图的内容的时候,强制垂直滚动的效果,所以这里使用ScrollView和ListView混合使用是没有意义的, … 阅读全文

使用SharedPreferences实现android程序自动登录和记住密码

  categories:android  tags:  author:

在目前的android软件中, 经常是需要登录的, 但是登录过程是比较麻烦的, 特别是我们的密码, 设置简单不安全, 设置复杂输入不方便, 因此自动记住密码, 自动登录功能是比较必要的。

本文提供一种简单的自动登录, 记住密码的功能, 这个仅仅简单的方法, 更安全的方法可以继续在这个基础上进行相关加密来实现。

一.自动登录相关需求

1. 记住密码, 是帮助用户记住密码, 减少用户输入的过程, 但是这个情况下 用户还是要选择登录 按钮进行登录

程序仅仅在用户登录成功后, 并且勾选了记住密码的选项后才将用户密码保存起来。

2. 自动登录, 是根据自动记录的用户和密码, 自动帮助用户到服务器登录, 判断登录是否成功, 若是登录成功自动跳转到 后续工作流程

若是登录不成功, 显示登录页面, 用户继续输入用户名和密码, 然后在登录

程序在判断登录成功后, 并且选择了 自动登录后, 自动保存用户名和密码,然后设置自动登录标志位。

下一次再次进入登录界面时,自动读入自动登录标志和用户名及密码, 代替用户登录,若是登录成功, 则进行后续操作,否则显示登录页面,要求用户登录。… 阅读全文

Android Studio中文乱码的解决

  categories:android  tags:  author:

一. 在android的源文件中的乱码问题

Android Studio安装后发现所有的中文,不管是界面上的还是输出的log中的中文都变成小框框,具体的解决方法如下,

wps495c.tmp[5]_thumb[1]

可以肯定是字体的问题
解决:菜单File->settings对话框,切换到Appearance标签
wps495d.tmp[4]_thumb[1]
选择override default fonts by, 先随便选择一个中文字体(PS:小框框都是中文字 呵呵),保存,重启软件,即可。 

二. Toast.makeText乱码问题,如下

wps496e.tmp[4]_thumb[1]

文件中乱码解决了, 发现软件在工作中, Toast有乱码,在网络上查找了很多办法如下:

编辑项目工程里的build.grandle 文件中添加一段代码即可

wps498e.tmp[4]_thumb[1]

tasks.withType(Compile) {    options.encoding = “UTF-8″}apply plugin: ‘android’android {}

也可以是:

tasks.withType(Compile) {
options.encoding = “UTF-8″
}

用最新的插件,有个配置参数0.6.+ 以后支持
android {
compileOptions.encoding = … 阅读全文

Android Studio新建Activity

  categories:android  tags:  author:

 

Android Studio是在google I/O大会上新发布的一个IDE,基于IntelliJ,Android开发除了Eclipse之外又多了一种选择。

在Android Studio中如何在当前项目中添加一个Activity?

1. 右键点Java包名, new — Android Component

wpsf2c6.tmp_thumb[1][1]
显示如下:

wpsf2e6.tmp_thumb[1][1]

创建如下类

wpsf2f7.tmp_thumb[1][1]

同时在xml文件中添加了如下内容

wpsf307.tmp_thumb[1][1]

2. 创建布局文件

不过这只是创建了java代码,还没有给这个activity创建layout。在res->layout上点右键, 选 New Layout resource file,输入layout 名字和需要的布局,Android Studio 会帮你创建layout并且切换到可见即所得视图进行界面设计:

wpsf308.tmp_thumb[1][1]

如下:

wpsf309.tmp_thumb[1][1]

创建完成如下:

wpsf31a.tmp_thumb[1][1]

为了让上面创建的这个layout资源,还需要在onCreate里加一句setContentView,如下:

public class aa extends Activity {

    public void onCreate(Bundle savedInstanceState) … 阅读全文

时尚的布袋

  categories:儿童作品  author:

image_thumb[1][1]

看那这个布袋又时尚又朴素,紫色的桌布上摆着白色的盘子,盘子上面有个绿色的茶杯… 阅读全文



快乐成长 每天进步一点点