精华内容
下载资源
问答
  • 摘要:这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样...

    摘要: 这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样的反模式也因为ajax的出现(异步加载)变的不是那么“反模式”了,其中又讲述了很多ejb的反模式,这些在轻量级框架流行的今天也早已经过时。

    这两天看了一本老书《bitter java》,第一次系统地了解了所谓“反模式”。就书的内容来说已经过于陈旧,书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌,而如web页面不能有太多元素这样的反模式也因为ajax的出现(异步加载)变的不是那么“反模式”了,其中又讲述了很多ejb的反模式,这些在轻量级框架流行的今天也早已经过时。不过书中有一个章节倒是挺有价值,讲述的是java的内存泄露问题,我认为是我目前读的关于这方面问题比较有价值的介绍。

    网上关于java内存泄露的资料都过于玄乎,其实java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。作者在书中提到了3个场景:

    1。流失监听器问题,在awt、swing编程中,给组件添加了事件监听器,这些组件的生命周期如果很长的话,监听器对象将不能被正确回收。关于GUI编程我不是很熟悉,这一点存有疑问,因为显然你触发一个按钮的事件,当然是一直期待同样的行为发生,如果删除了监听器或者使用弱引用让JVM回收不符合业务逻辑和用户体验。

    2。集合类,集合类仅仅有添加元素的方法,而没有相应的删除机制,导致内存被占用。这一点其实也不明确,这个集合类如果仅仅是局部变量,根本不会造成内存泄露,在方法栈退出后就没有引用了会被jvm正常回收。而如果这个集合类是全局性的变量(比如类中的静态属性,全局性的map等),那么没有相应的删除机制,很可能导致集合所占用的内存只增不减,因此提供这样的删除机制或者定期清除策略非常必要。

    3。单例模式。不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露,考虑下面的例子:

    class A{

    public A(){

    B.getInstance().setA(this);

    }

    ....

    }

    //B类采用单例模式

    class B{

    private A a;

    private static B instance=new B();

    public B(){}

    public static B getInstance(){

    return instance;

    }

    public void setA(A a){

    this.a=a;

    }

    //getter...

    }

    显然B采用singleton模式,他持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较大的对象或者集合类型会发生什么情况。

    上面所讲的这些也启发我们如何去查找内存泄露问题,第一选择当然是利用工具,比如jprofiler,第二就是在代码复审的时候关注长生命周期对象:全局性的集合、单例模式的使用、类的static变量等等。

    文章转自庄周梦蝶  ,原文发布时间 2007-11-11

    展开全文
  • 在本文中,我们将看到Java内存泄漏的示例代码。之后,我们将把Java应用程序连接到JConsole,比较有无内存泄漏时应用程序的内存使用情况。深入研究JConsole的内存监控工具可以让我们看到堆内存是如何划分为不同的...

    在本文中,我们将看到Java中内存泄漏的示例代码。之后,我们将把Java应用程序连接到JConsole,比较有无内存泄漏时应用程序的内存使用情况。深入研究JConsole的内存监控工具可以让我们看到堆内存是如何划分为不同的空间的,垃圾收集器是如何有效地管理Java应用程序的内存的。

    Java中的垃圾回收

    在Java中,垃圾收集器(GC)负责释放未使用对象使用的内存。任何没有引用的对象都可以进行垃圾收集,如下图所示。因此,GC中的第二个对象可以被设置为空。

    d0dd48d15d54f602842107739f0af55b.png

    什么是Java内存泄漏

    当程序无法释放未使用的内存时,会导致内存泄漏,这可能导致意外结果或应用程序崩溃。尽管Java中没有关于内存泄漏的正式定义,但为了便于理解,我们可以将其大致分为两类。

    运行代码无法访问的对象导致的内存泄漏。

    可通过运行代码访问但不会再次使用的对象导致的内存泄漏。

    第一种内存泄漏发生在对对象的引用不再出现在正在运行的代码中,但垃圾收集器仍然无法为这些对象释放空间时。

    第二种内存泄漏主要是由于程序中的错误逻辑造成的,在该程序中,对未使用对象的引用保留在运行代码中(即使该对象将不再被使用),这不允许GC回收内存。一些开发人员将此泄漏视为“实际内存泄漏”,因为将引用设置为null将允许GC回收内存。但是,如果代码已经部署,则无法将未使用对象的引用设置为null。在下面的例子中,我们将考虑这种泄漏。

    Java程序内存泄漏示例

    让我们考虑一个现实生活中的例子,狗收容所的狗被添加到收容所,并从收容所移除时,他们被领养。

    这个Dog.java类有下面描述的三个变量:

    microchip ID–唯一标识狗。

    name–表示狗名的可选变量。

    字节数组–为了加速内存泄漏,我们有一个10Mb的字节数组。

    /** The Unique MicroChip ID of the dog. */

    private int microChipID;

    /** The name of the dog. */

    private String name;

    /** Extra memory space for each instance to speed up the memory leak. */

    private byte[] toExpediteLeak;

    下面是可能导致内存泄漏的有问题的代码段。在overrided equals方法中,我们通过将microchip ID和Dog name相等来比较两个Dog对象。由于狗的名字可以更改,因此使用它来等同于两个狗对象可能会导致意外的结果。例如,如果存储在HashSet中的Dog对象是使用旧名称存储的,并且我们尝试使用新名称删除它,那么删除该Dog对象将失败。

    @Override

    public boolean equals(Object obj) {

    if (obj == this)

    return true;

    if (!(obj instanceof Dog))

    return false;

    Dog dog = (Dog) obj;

    return dog.microChipID == microChipID && dog.name.equals(name);

    }

    这个狗狗庇护所DogShelter.java类负责将目前在收容所的狗的名单保存在一个HashSet中,如下所示。

    /** In Memory Store containing the dogs present in the shelter. */

    private Set shelterDogs = new HashSet();

    这个类公开了两个公共方法,可以用来添加和删除收容所中的狗。

    public void addEntry(int microChipID, String name) {

    Dog dog = new Dog(microChipID, name);

    shelterDogs.add(dog);

    }

    public void removeEntry(int microChipID) {

    Dog dog = new Dog(microChipID);

    shelterDogs.remove(dog);

    }

    请注意,我们使用Microchip ID和name添加dog对象,而仅使用Microchip ID删除dog对象。但是,要从集合中实际删除dog对象,我们需要同时提供Microchip ID和dog名称,因为重写equals方法时使用的逻辑错误。

    最后,为了触发内存泄漏,我们将在HashSet中连续添加和删除Dog对象。

    public void addAndRemoveRandomEntries(int entriesCount) {

    Random rand = new Random();

    String[] commonDogNames = { "Buddy", "Coco", "Charlie", "Cooper", "Maggie" };

    for (int i = 0; i <= entriesCount; i++) {

    /** Generate a random dog name from the list of common dog names. */

    String randomDogName = commonDogNames[rand.nextInt(commonDogNames.length)];

    /** First add and then remove the entry from the HashSet. */

    addEntry(i, randomDogName);

    removeEntry(i);

    System.out.printf("Successfuly removed entry for %s with unique id %d.\n", randomDogName, i);

    try {

    /**

    * Sleep before adding & removing new entry so that we can see the memory grow

    * in JConsole.

    */

    Thread.sleep(500);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    让我们运行main方法,看看我们的程序是如何在几秒钟内崩溃的

    public static void main(String[] args) {

    DogShelter shelter = new DogShelter();

    shelter.addAndRemoveRandomEntries(1000);

    }

    如何使用JConsole监控Java应用程序的内存使用

    在运行main方法之后,打开JConsole并将其连接到本地Java进程。

    将JConsole连接到本地Java进程之后,如果单击Memory选项卡,您将看到如下所示的窗口。让我们深入讨论一下内存工具的每个特性。

    c4000613004e2a1637206aaf9f55de02.png

    堆VS非堆空间

    在JConsole窗口的右下角,我们可以看到几个代表当前内存使用百分比的条形图。内存空间分为堆空间和非堆空间。

    堆空间

    使用new关键字创建的对象会落在堆空间中。在一个典型的Java程序中,由于不断地创建和删除新对象,我们需要一种机制来恢复未使用对象的内存。垃圾收集器负责实际释放这些未使用对象的内存,为了有效地执行此过程,堆内存被划分为3个不同的空间。

    1. Eden 伊甸园空间-新创建的对象出现在伊甸园空间中。

    2. Survivor 幸存者空间–伊甸园空间中在垃圾收集中幸存的对象被提升到幸存者空间。

    3. Old Gen–在幸存者空间中的垃圾收集中存活很长时间的对象被提升为Old Gen或Tenured Generation。

    GC在老年代空间中运行的频率较低,因为老年代的对象生活在该空间中。而GC在Eden空间上运行得更频繁,因为新对象更容易被取消引用。堆内存的这种分离允许有效的内存管理。

    非堆空间

    非堆空间分为元空间、代码缓存和压缩类空间。

    Metaspace存储描述用户类的元数据。所以所有与类相关的数据,比如静态方法和原语类型变量都存储在这里。在Java8之前,使用PermGen代替元空间。与PermGen相比,元空间具有以下优点:

    元空间使用本机内存,而不是像PermGen那样使用堆。

    元空间不再具有固定的大小,它会自动增加到某个限制(可以使用JVM参数指定)。而PermGen的大小是固定的。

    当内存达到MaxMetaspaceSize时,会触发垃圾回收以删除未使用的类定义和装入器。

    代码缓存空间用于存储本机代码,以便Just-In-Time(JIT)编译器更快地执行Java程序。

    了解JConsole内存图表

    在JConsole窗口的顶部,您可以看到有多个内存图表。让我们分析所有堆内存图表,并比较有无内存泄漏的Java应用程序中的内存使用情况。需要注意的是,下面显示的内存图表模式是特定于这个特定Java应用程序的。

    堆内存图表

    堆内存图表显示了在Eden空间、幸存者空间和老年代空间中使用的组合内存。堆内存图表本身足以监视Java应用程序的内存,并可能检测内存泄漏。

    内存泄漏

    在程序执行过程中,随着内存泄漏操作的不断重复,堆内存不断增长。

    如果内存泄漏的操作重复多次,程序最终将崩溃并出现OutOfMemoryError。

    内存泄漏已修复

    堆内存的使用随着操作的多次重复而增加,并且一旦GC触发,未使用的对象所使用的内存就会被回收。

    如果将完全相同的操作重复多次,我们可以看到,在GC循环完成后,内存使用量几乎在同一个位置(~10mb)增加。

    975184eca3b944f726cfead4897fe1b8.png

    Eden 伊甸园空间图

    内存泄漏

    直到时间14:16,新的狗的物体从伊甸园空间被分配了记忆。

    有趣的是,在14:16之后,新的Dog对象直接从老年代空间分配内存。

    对于这种行为的一种可能解释是,JVM标识在GC循环完成后所有Dog对象都会在老年代空间中登陆。因此,JVM直接从老年代分配内存,跳过了将对象从Eden空间转移到幸存者空间,最后转移到老年代空间的过程。

    内存泄漏已修复

    内存图表与堆内存图表几乎相同,因为Dog对象被创建,引用被立即删除,因此它们可以进行垃圾收集。

    c1fb7e06b07135161e5865c1a6d800a5.png

    Survivor 幸存者空间图

    内存泄漏

    直到时间14:16,在伊甸园空间中幸存下来的狗对象被转移到幸存者空间。

    在14:16之后,狗对象直接从老年代空间分配内存,因此幸存者空间的内存下降。

    内存泄漏已修复

    GC从伊甸园空间本身回收内存,因此狗对象不会转移到幸存者空间,我们几乎一直在使用内存。

    19b3073c9991e462234be10cf481930f.png

    老年代空间图

    内存泄漏

    直到14:16,我们看到,由于狗的对象被从伊甸园空间转移到幸存者空间,最后转移到老年代空间,步幅增加。

    14:16之后,我们看到内存几乎持续增长,因为Dog对象直接从老年代空间分配内存。

    内存可达2.6GB。

    内存泄漏已修复

    即使内存图表看起来与内存泄漏的图表相似。然而,我们可以看到老年代空间的内存几乎没有达到6mb。

    ff6e7262324eda7e7599c9b806da0dcc.png

    假设您有一个事件触发了一个覆盖5000多行代码的操作,并且您怀疑它有内存泄漏。检查所有代码并尝试确定您的代码是否存在内存泄漏将是非常具有挑战性和耗时的。但是,如果我们的应用程序使用jconsole可以很容易地找到主要的内存泄漏。

    1. 运行Java应用程序并将JConsole连接到它。

    2. 重复您怀疑内存泄漏的操作。例如,如果您怀疑向数据库中添加条目的操作可能存在内存泄漏,那么请编写一个测试脚本,该脚本将在一段时间内重复相同的操作,在此期间您可以检测到可能的内存泄漏。

    3. 每隔几分钟单击JConsole窗口右上角的“perform gc”。例如,当您的操作在后台连续运行时,您可以请求在10分钟内每分钟执行一次GC。

    863eaa4b502cfa6073801dc812c3f762.png

    4. 分析如下所示的结果,以确定Java应用程序是否存在内存泄漏。

    结果分析

    要分析结果,请在GC操作完成后连接所有点(从步骤3开始)。

    如果连接的直线/曲线正在增加或具有正斜率,则会发生内存泄漏。

    d2642ce4fd3878ec0448f7d85686155f.png

    但是,如果连接的直线/曲线不增加,则可能没有内存泄漏。

    d87897b39d9d14557cffe5a991d8cded.png

    步骤4中的行将与内存泄漏的大小成比例增加。如果内存泄漏很小,则曲线将缓慢增加。但是,如果内存泄漏很大,则线将以更大的斜率增加。因此,如果内存泄漏以千字节为单位,则使用此技术可能无法看到它。

    展开全文
  • 解决Java加载dll导致Java进程内存泄露在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~ 这个问题奇怪的地方...

    解决Java加载dll导致Java进程内存泄露在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~  这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。  测试代码如下:System.loadLibrary("test1");int threadPoolSize =

    解决Java加载dll导致Java进程内存泄露

    在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~

    这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。

    测试代码如下:System.loadLibrary("test1");

    int threadPoolSize =

    400;

    ExecutorService service = Executors.newFixedThreadPool(threadPoolSize);

    for (int i =

    0; i <

    400; i++) {

    service.submit(new Runnable() {

    public

    void run() {

    while (true) {

    try {

    Thread t =

    new Thread();

    t.start();

    Thread.sleep(100);

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    });

    }

    说明:此段代码所做的工作就是加载一个dll,然后不断的启动线程(线程什么也不做,直接终止)。

    注:线程池只是为了加速问题复现,无其他用处。

    现象:

    1.如果不加载dll,只不断的启动线程,Java进程内存正常,不会一直增长。

    2.如果加载附件中test1的

    msimg32.dll

    ,Java进程内存会一直增长。

    3.如果加载附件中test2的dll(需要安装C++运行环境vcredist_x86),Java进程内存正常,不会一直增长。

    DLL说明:

    dll的工程源码在附件中,test1和test2的区别只在于编译选项,如附件:test1选择的是“使用标准Windows库”或“在静态库中使用MFC”,test2选择的是“在共享DLL中使用MFC”

    此dll工程的特点在于使用了jni,并引入了mfc头文件【#include 】,如果不引入mfc头文件则不会引起内存泄漏

    目前此问题的根本原因尚不明确,怀疑是jdk的bug(使用最新的jdk1.6.0.23也没用),不知道大家有什么想法吗?欢迎大家讨论~

    基于广大用户反馈,论坛附件下载策略全新上线,下载券全站通用,请放心下载 。

    收藏0

    打赏0

    点赞0

    分享至:

    评论

    文明留言,专业沟通

    4d2a07ae94f6972507ccebf791e8f739.png

    请先 登录,再评论!

    全部评论

    相关推荐

    展开全文
  • Handler导致内存泄露分析 有关内存泄露请猛戳内存泄露 Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // do something. } } 当我们这样创建Handler的时候Android ...

    Handler导致内存泄露分析

    有关内存泄露请猛戳内存泄露

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
    	    // do something.
        }
    }
    

    当我们这样创建Handler的时候Android Lint会提示我们这样一个warning: In Android, Handler classes should be static or leaks might occur.

    一直以来没有仔细的去分析泄露的原因,先把主要原因列一下:

    • Android程序第一次创建的时候,默认会创建一个Looper对象,Looper去处理Message Queue中的每个Message,主线程的Looper存在整个应用程序的生命周期.
    • Hanlder在主线程创建时会关联到LooperMessage Queue,Message添加到消息队列中的时候Message(排队的Message)会持有当前Handler引用,
      Looper处理到当前消息的时候,会调用Handler#handleMessage(Message).就是说在Looper处理这个Message之前,
      会有一条链MessageQueue -> Message -> Handler -> Activity,由于它的引用导致你的Activity被持有引用而无法被回收
    • 在java中,no-static的内部类会隐式的持有当前类的一个引用。static的内部类则没有。

    具体分析

    public class SampleActivity extends Activity {
    
      private final Handler mHandler = new Handler() {
    		@Override
    		public void handleMessage(Message msg) {
    		  // do something
    		}
      }
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    	// 发送一个10分钟后执行的一个消息
    	mHandler.postDelayed(new Runnable() {
    	  @Override
    	  public void run() { }
    	}, 600000);
    
    	// 结束当前的Activity
    	finish();
    }
    

    finish()的时候,该Message还没有被处理,Message持有Handler,Handler持有Activity,这样会导致该Activity不会被回收,就发生了内存泄露.

    解决方法

    • 通过程序逻辑来进行保护。
      • 如果Handler中执行的是耗时的操作,在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,
        Activity自然会在合适的时候被回收。
      • 如果Handler是被delayMessage持有了引用,那么在ActivityonDestroy()方法要调用Handlerremove*方法,把消息对象从消息队列移除就行了。
        • 关于Handler.remove*方法
          • removeCallbacks(Runnable r) ——清除r匹配上的Message。
          • removeC4allbacks(Runnable r, Object token) ——清除r匹配且匹配token(Message.obj)的Message,token为空时,只匹配r。
          • removeCallbacksAndMessages(Object token) ——清除token匹配上的Message。
          • removeMessages(int what) ——按what来匹配
          • removeMessages(int what, Object object) ——按what来匹配
            我们更多需要的是清除以该Handlertarget的所有Message(Callback)就调用如下方法即可handler.removeCallbacksAndMessages(null);
    • Handler声明为静态类。
      静态类不持有外部类的对象,所以你的Activity可以随意被回收。但是不持有Activity的引用,如何去操作Activity中的一些对象? 这里要用到弱引用
    public class MyActivity extends Activity {
    	private MyHandler mHandler;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		mHandler = new MyHandler(this);
    	}
    
    	@Override
    	protected void onDestroy() {
    		// Remove all Runnable and Message.
    		mHandler.removeCallbacksAndMessages(null);
    		super.onDestroy();
    	}
    
    	static class MyHandler extends Handler {
    		// WeakReference to the outer class's instance.
    		private WeakReference<MyActivity> mOuter;
    
    		public MyHandler(MyActivity activity) {
    			mOuter = new WeakReference<MyActivity>(activity);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			MyActivity outer = mOuter.get();
    			if (outer != null) {
    				// Do something with outer as your wish.
    			}
    		}
    	}
    }
    
    展开全文
  • 【IT168技术】在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~这个问题奇怪的地方在于是Java进程内存泄露,...
  • 8.2 使用ThreadLocal不当可能会导致内存泄露基础篇已经讲解了ThreadLocal的原理,本节着重来讲解下使用ThreadLocal会导致内存泄露的原因,并讲解使用ThreadLocal导致内存泄露的案例。8.2.1 为何会出现内存泄露基础篇...
  • GC只是回收失去引用的对象,但是,由于程序设计失误导致的对象始终被引用,会导致内存泄漏,如下面的代码。用数组实现了一个栈, 支持入栈和出栈操作。import java.util.EmptyStackException;/*** Created by ...
  • 前言在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露、强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这样情况发生,增强系统的健壮...
  • java内存泄露

    2013-02-28 15:14:19
    java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的...
  • java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的...
  • 本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助。Java内存管理机制在C++ 语言中,如果需要动态分配一块内存,程序猿需要负责...
  • NULL 博文链接:https://cyj86.iteye.com/blog/1095213
  • 这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存泄露Java 语言对内存管理做了自己的优化,这就是垃圾回收机制。 Java 的几乎所有内存对象都是在堆内存上分配(基本数据...
  • 这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存泄露Java 语言对内存管理做了自己的优化,这就是垃圾回收机制。 Java 的几乎所有内存对象都是在堆内存上分配(基本数据...
  • 这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存泄露Java语言对内存管理做了自己的优化,这就是垃圾回收机制。Java的几乎所有内存对象都是在堆内存上分配(基本数据类型...
  • 这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存泄露Java 语言对内存管理做了自己的优化,这就是垃圾回收机制。 Java 的几乎所有内存对象都是在堆内存上分配(基本数据...
  • 内存溢出 out of memory...内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。memory leak会最终会导致out...
  • 在定位JVM性能问题时可能会遇到内存泄露导致JVM OutOfMemory的情况,在使用Tomcat容器时如果设置了reloadable=”true”这个参数,在频繁热部署应用时也有可能会遇到内存溢出的情况。Tomcat的热部署原理是检测到WEB-INF...
  • 本文重点不在于介绍如何使用HashMap,而是关注在使用HashMap过程中,可能会导致内存泄露的情况,下面将以示例的形式展开具体介绍。注意:理解本文的前提需要先熟悉HashMap原理。为了更快的看到java.lang....
  • 虽然Java拥有垃圾回收机制,但同样会出现内存泄露问题,我们说一下比较主要的三种情况。 1. 静态类的使用 诸如 HashMap、Vector 等集合类的静态使用最容易出现内存泄露,因为这些静态变量的生命周期和应用程序一致...
  • 本文详细地介绍了Java内存管理的原理,以及内存泄露产生的原因,同时提供了一些列解决Java内存泄露的方案,希望对各位Java开发者有所帮助。Java内存管理机制在C++ 语言中,如果需要动态分配一块内存,程序员需要负责...
  • java内存泄露与内存溢出基本概念内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。内存溢出:指程序运行过程中无法申请到足够的内存而导致的一...
  • 在使用各种 listener 时,稍有不注意就会导致内存泄露,因此在使用延时返回的回调时,需要格外小心。demo先看一个的 demo:MainActivity 点击按钮后,调用 LongTimeOperation 开启一个耗时 10 秒的线程,并在执行...
  • java内存泄露

    2012-04-06 22:50:06
    网上关于java内存泄露的资料都过于玄乎,其实java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,516
精华内容 606
关键字:

java导致内存泄露

java 订阅