精华内容
下载资源
问答
  • Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的内存泄漏. 查找原因会十分困难. 有两类主要的Java内存泄漏: * 不再需要...

    ● 请问,在java中会存在内存泄漏吗?请简单描述一下。

    考察点:内存

    参考回答:

    Java中的确存在Java的内存泄漏, 并且事态可以变得相当严重

    Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的内存泄漏. 查找原因会十分困难.
    有两类主要的Java内存泄漏:
    * 不再需要的对象引用
    * 未释放的系统资源
    2.2 非必要的对象引用
    Java代码常常保留对于不再需要的对象引用, 并且这组织了内存的垃圾收集器的工作. Java对象通常被其他对象包含引用, 为此一个单一对象可以保持整个对象树在内存中, 于是导致了如下问题:
    * 在向数组添加对象以后遗漏了对于他们的处理
    * 直到你再次使用对象的时候都不释放引用. 比如一个菜单指令可以插件一个对象实例引用并且不释放便于以后再次调用的时候使用, 但是也许永远不会发生.
    * 在其他引用依然需要旧有状态的时候贸然修改对象状态. 比如当你为了在一个文本文件里面保存一些属性而使用一个数组, 诸如”字符个数”等字段在不再需要的时候依然保留在内存当中.
    * 允许一个长久执行的线程所引用的对象. 设置引用为NULL也无济于事, 在线程退出和空闲之前, 对象不会被收集释放
    2.3 未释放的系统资源
    Java方法可以定位Java实例意外的堆内存, 诸如针对视窗和位图的内存资源. Java常常通过JNI(Java Native Interface)调用C/C++子程序定位这些资源.

    展开全文
  • 考察点:内存Java中的确存在Java的内存泄漏, 并且事态可以变得相当严重Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的...

    考察点:内存

    Java中的确存在Java的内存泄漏, 并且事态可以变得相当严重

    Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的内存泄漏. 查找原因会十分困难.

    有两类主要的Java内存泄漏:

    * 不再需要的对象引用

    * 未释放的系统资源

    2.2 非必要的对象引用

    Java代码常常保留对于不再需要的对象引用, 并且这组织了内存的垃圾收集器的工作. Java对象通常被其他对象包含引用, 为此一个单一对象可以保持整个对象树在内存中, 于是导致了如下问题:

    * 在向数组添加对象以后遗漏了对于他们的处理

    * 直到你再次使用对象的时候都不释放引用. 比如一个菜单指令可以插件一个对象实例引用并且不释放便于以后再次调用的时候使用, 但是也许永远不会发生.

    * 在其他引用依然需要旧有状态的时候贸然修改对象状态. 比如当你为了在一个文本文件里面保存一些属性而使用一个数组, 诸如”字符个数”等字段在不再需要的时候依然保留在内存当中.

    * 允许一个长久执行的线程所引用的对象. 设置引用为NULL也无济于事, 在线程退出和空闲之前, 对象不会被收集释放

    2.3 未释放的系统资源

    Java方法可以定位Java实例意外的堆内存, 诸如针对视窗和位图的内存资源. Java常常通过JNI(Java Native Interface)调用C/C++子程序定位这些资源.

    展开全文
  • SrsAutoFree模式,避免内存泄漏和错误

    千次阅读 2013-10-30 09:23:22
    内存不释放就会泄漏,多次释放就会段错误,越界更恐怖。 不释放和多次释放都可以用SrsAutoFree规避,越界就需要工具和经验的问题。 释放和多次释放,原因是内存或者对象的生命周期过程,譬如在一个while循环中,有些...

    C/C++中内存是一个很难处理的事情,正如强项就是弱项,强大的地方也是致命的地方。

    内存不释放就会泄漏,多次释放就会段错误,越界更恐怖。

    不释放和多次释放都可以用SrsAutoFree规避,越界就需要工具和经验的问题。

    释放和多次释放,原因是内存或者对象的生命周期过程,譬如在一个while循环中,有些时候要释放,有些时候continue就好,就容易出问题。

    真的需要活N久的对象吗?很少。大部分的作用域在当前函数和子函数,局部变量就可以搞定,是的,有些时候就是没有办法用局部变量,譬如由一个函数收取的包,在当前函数就需要释放。

    考虑下面的逻辑:

    int SrsClient::publish(SrsSource* source, bool is_fmle)
    {
    	int ret = ERROR_SUCCESS;
    	
    	SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
    	
    	while (true) {
    		// switch to other st-threads.
    		st_usleep(0);
    		
    		SrsCommonMessage* msg = NULL;
    		if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
    			srs_error("recv identify client message failed. ret=%d", ret);
    			return ret;
    		}
    
    		SrsAutoFree(SrsCommonMessage, msg, false);
    		
    		pithy_print.set_age(msg->header.timestamp);
    
    		// reportable
    		if (pithy_print.can_print()) {
    			srs_trace("<- clock=%u, time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", 
    				(int)srs_get_system_time_ms(), pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
    		}
    		
    		// process audio packet
    		if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {
    			srs_error("process audio message failed. ret=%d", ret);
    			return ret;
    		}
    		// process video packet
    		if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) {
    			srs_error("process video message failed. ret=%d", ret);
    			return ret;
    		}
    		
    		// process onMetaData
    		if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
    			if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
    				srs_error("decode onMetaData message failed. ret=%d", ret);
    				return ret;
    			}
    		
    			SrsPacket* pkt = msg->get_packet();
    			if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
    				SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
    				if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) {
    					srs_error("process onMetaData message failed. ret=%d", ret);
    					return ret;
    				}
    				srs_trace("process onMetaData message success.");
    				continue;
    			}
    			
    			srs_trace("ignore AMF0/AMF3 data message.");
    			continue;
    		}
    		
    		// process UnPublish event.
    		if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) {
    			if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
    				srs_error("decode unpublish message failed. ret=%d", ret);
    				return ret;
    			}
    			
    			// flash unpublish.
    			if (!is_fmle) {
    				srs_trace("flash publish finished.");
    				return ret;
    			}
    		
    			SrsPacket* pkt = msg->get_packet();
    			if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
    				SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt);
    				return rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id);
    			}
    			
    			srs_trace("ignore AMF0/AMF3 command message.");
    			continue;
    		}
    	}
    	
    	return ret;
    }
    从RTMP协议栈拿到包后,使用在这个作用域一定会释放,所以使用AutoFree就可以保证只释放一次,而且一定释放一次。

    AutoFree实现很可靠,用C++的构造和析构,以及宏定义就可以搞定。

    /*
    The MIT License (MIT)
    
    Copyright (c) 2013 winlin
    
    Permission is hereby granted, free of charge, to any person obtaining a copy of
    this software and associated documentation files (the "Software"), to deal in
    the Software without restriction, including without limitation the rights to
    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
    the Software, and to permit persons to whom the Software is furnished to do so,
    subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */
    
    #ifndef SRS_CORE_AUTO_FREE_HPP
    #define SRS_CORE_AUTO_FREE_HPP
    
    /*
    #include 
    */
    
    #include 
    
    /**
    * auto free the instance in the current scope.
    */
    #define SrsAutoFree(className, instance, is_array) \
    	__SrsAutoFree _auto_free_##instance(&instance, is_array)
        
    template
    class __SrsAutoFree
    {
    private:
        T** ptr;
        bool is_array;
    public:
        /**
        * auto delete the ptr.
        * @is_array a bool value indicates whether the ptr is a array.
        */
        __SrsAutoFree(T** _ptr, bool _is_array){
            ptr = _ptr;
            is_array = _is_array;
        }
        
        virtual ~__SrsAutoFree(){
            if (ptr == NULL || *ptr == NULL) {
                return;
            }
            
            if (is_array) {
                delete[] *ptr;
            } else {
                delete *ptr;
            }
            
            *ptr = NULL;
        }
    };
    
    
    #endif
    

    对比以下代码,没有使用auto free模式:

    // ignore when no messages.
    int count = (int)msgs.size();
    if (msgs.empty()) {
            continue;
    }
    
    // all msgs to forward.
    int i = 0;
    for (i = 0; i < count; i++) {
            SrsSharedPtrMessage* msg = msgs[i];
            msgs[i] = NULL;
    
            // we erased the sendout messages, the msg must not be NULL.
            srs_assert(msg);
            
            ret = client->send_message(msg);
            if (ret != ERROR_SUCCESS) {
                    srs_error("forwarder send message to server failed. ret=%d", ret);
    
                    // convert the index to count when error.
                    i++;
                    
                    break;
            }
    }
    
    // clear sendout mesages.
    if (i < count) {
            srs_warn("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);
    } else {
            srs_info("clear forwarded msg, total=%d, forwarded=%d, ret=%d", count, i, ret);
    }
    msgs.erase(msgs.begin(), msgs.begin() + i);
    
    if (ret != ERROR_SUCCESS) {
            break;
    }

    使用auto free模式后:

    // ignore when no messages.
    if (count <= 0) {
        srs_verbose("no packets to forward.");
        continue;
    }
    SrsAutoFree(SrsSharedPtrMessage*, msgs, true);
    
    // all msgs to forward.
    for (int i = 0; i < count; i++) {
        SrsSharedPtrMessage* msg = msgs[i];
        
        srs_assert(msg);
        msgs[i] = NULL;
        
        if ((ret = client->send_message(msg)) != ERROR_SUCCESS) {
            srs_error("forwarder send message to server failed. ret=%d", ret);
            return ret;
        }
    }
    

    如下图:


    展开全文
  • 监控java内存泄漏

    2015-07-21 15:56:17
    如果有些系统的性能不是很稳定,随着时间的变化而变化,那么就要... 事实上,有些内存泄漏是无法通过其它手段避免的,只能由编程开发人员在编程的时候主动避免。Java虚拟机的确可以将没有用的对象自动回收掉,可是有些
    如果有些系统的性能不是很稳定,随着时间的变化而变化,那么就要怀疑系统是否存在内存泄漏了。特别是哪些随时间的推移越来越慢的系统,很大程度上是Java内存对象有了泄漏。 
      
        不是说Java虚拟机是自动回收内存吗?怎么还存在内存泄漏? 
        事实上,有些内存泄漏是无法通过其它手段避免的,只能由编程开发人员在编程的时候主动避免。Java虚拟机的确可以将没有用的对象自动回收掉,可是有些泄漏是程序员的疏漏,一直保持了本应该释放的对象,因此Java虚拟机不认为这些对象是没有用的,因为他们跟其它有用的对象没什么区别,还有引用指着这些对象。这种情况就只能从源码着手了,找出内存泄漏的根源。Java虚拟机提供了很多工具来定位内存泄漏的位置。在Sun的Hotspot中,主要有jmap和jhat。 

    jmap 

    jmap命令用于查看当前java进程或者core dump文件,显示当前存在与内存中的对象分布情况,包括对象所属的类,对象的个数和所占内存的大小,并且依所占用的内存大小的顺序排列。用下面命令查找java的pid:

    ps -ef|grep java  

    然后查看java进程的内存对象分布: 

    jmap -histo pid  

    结果如图: 

    C:\Documents and Settings\Administrator>jmap -histo 180  
      
     num     #instances         #bytes  class name  
    ----------------------------------------------  
       1:         13352       60321384  [B  
       2:        108823       13516768  <constMethodKlass>  
       3:         89912        9476704  [C  
       4:        108823        8710200  <methodKlass>  
       5:        152780        6715552  <symbolKlass>  
       6:          8796        5325984  <constantPoolKlass>  
       7:          8796        4219536  <instanceKlassKlass>  
       8:         16753        3896104  [I  
       9:          7026        2782816  <constantPoolCacheKlass>  
      10:        109717        2633208  java.lang.String  
      11:         40391         969384  java.util.HashMap$Entry  
      12:         13806         932104  [Ljava.lang.Object;  
      13:          9400         902400  java.lang.Class  
      14:          8076         854312  [Ljava.util.HashMap$Entry;  
      15:         11426         794936  [S  
      16:         13935         685408  [[I  

    但是有时候光知道对象的数量和内存占用量是不够的,因为这些数据只是提供了有可能泄漏的对象,没有告诉这些对象是什么地方分配的。要定位内存泄漏还需要更多的信息。这时候就需要jhat工具了。 

    jhat在使用jhat之前,还需要用jmap获得更加详细的数据。一般用下面命令获得一个二进制的输出文件: 

    Java代码  收藏代码
    1. C:\Documents and Settings\Administrator>jmap -dump:file=heap.bin 180  
    2. Dumping heap to C:\Documents and Settings\Administrator\heap.bin ...  
    3. Heap dump file created  


    然后用下面的命令用jhat来分析这个文件: 

    Java代码  收藏代码
    1. C:\Documents and Settings\Administrator>jhat -J-mx512m heap.bin  
    2. Reading from heap.bin...  
    3. Dump file created Mon Dec 06 23:36:22 CST 2010  
    4. Snapshot read, resolving...  
    5. Resolving 713062 objects...  
    6. .................  
    7. Eliminating duplicate references................................................  
    8. ......................................................................Snapshot resolved.  
    9. Started HTTP server on port 7000  
    10. Server is ready.  


    这个命令会启动一个Web服务器,并在7000端口上监听。这时候可以借助浏览器访问http://localhost:7000,这个页面可以看到很多详细的信息,包括哪些对象是哪些类创建的。可以从http://localhost:7000/histo/入手,这个页面不但可以看到当前内存中对象的情况,还可以点击每一种对象来查找哪些正在使用此对象的其它对象,如下图: 



    另外http://localhost:7000/showInstanceCounts/includePlatform/页面可以想jmap命令一样,提供对象实例的数量和大小的信息,如下图: 




    此外值得一提的是查询页面http://localhost:7000/oql/,这个页面可以让你输入类似数据库sql查询语句,根据需求定位到相关的信息,如下图: 



     

    展开全文
  • 前言相信大家一定听过,看过甚至遇到过内存泄漏。在 .NET 平台也一定知道有垃圾回收器,它可以让开发人员不必担心内存的释放问题,因为它会自定管理内存。但是在 .NET 平台下进行编程,绝对不会发生内存泄漏的问题...
  • 内存泄漏的监控

    2010-12-07 00:01:43
    如果有些系统的性能不是很稳定,随着时间的变化而变化,那么就要怀疑系统是否存在... 事实上,有些内存泄漏是无法通过其它手段避免的,只能由编程开发人员在编程的时候主动避免。Java虚拟机的确可以将没有用的对象自...
  • 相信大家一定听过,看过甚至遇到过内存泄漏。在 .NET 平台也一定知道有垃圾回收器,它可以让开发人员不必...本文就讨论下 .NET 平台的垃圾回收器是如何工作的,进而当我们在编写 .NET 程序时避免发生内存泄漏的问题...
  • 这样,每个进程都获得了自己可以使用的地址空间,可以访问比您物理上安装的内存更多的内存。 在 32-位 x86 系统上,每一个进程可以访问 4 GB 内存。现在,大部分人的系统上并没有 4 GB 内存,即使您将 swap 也...
  • 操作系统(内存管理)

    热门讨论 2009-09-20 12:55:25
    文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半...
  • 某些过程化程序设计语言也可实现面向对象系统答:JAVA程序会在编译和运行的时候自动的检测可能出现的错误,而且它是一种强类型语言,对于类型的检查很严格,而且它的垃圾回收机制也有效的避免内存泄漏。...
  • 一、智能指针的作用智能指针的作用 :智能指针可以帮助我们避免在申请空间后忘记释放造成内存泄漏的问题;因为智能指针本身是一个类(后面也会自己实现一下),当出了类的作用域的时候,类会调用析构函数进行释放资源...
  • 使用Jetpack全家桶的同学相信对LiveData都不陌生,其可以在很大程度上避免内存泄漏、更好的将View层与Model层分离等诸多优点使得LiveData在MVVM模式中开发成为不可或缺的利器。今天我们就将LiveData剖开来瞧瞧,为何...
  • 如果你不注意,可能出现内存泄漏问题。 本文将讲解事件处理函数的不同形式,理解了这些可以避免编写代码的时候出现内存相关的问题。 本文内容典型的事件处理函数变种事件处理函数编译器类型转换不是同一个委托实例`...
  • Handerl如何避免内存泄漏 更新view,难道只能在UI线程吗?子线程不可以吗? 子线程中为什么不能创建Handler new Handler的两种方式区别 ThreadLocal用法及原理 一、Handerl如何避免内存泄漏 1、首先写一段内存...
  • C++基础复习

    2020-09-05 21:57:11
    this指针可以为空吗类的6大默认成员函数默认构造函数初始化列表注意初始化顺序静态成员特性静态成员函数可以调用非静态成员函数吗友元函数友元类内部类C++内存分布new/delete与malloc/free的区别什么是内存泄漏,...
  • 的确存在Java的内存泄漏, 并且事态可以变得相当严重 Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的内存泄漏. 查找...
  • QQ面试6

    2008-11-26 16:09:47
    的确存在Java的内存泄漏, 并且事态可以变得相当严重Java garbage collector自动释放哪些内存里面程序不在需要的对象, 以此避免大多数的其他程序上下文的内存泄漏. 但是Java应用程序依旧会有相当的内存泄漏. 查找原因...
  • 答:JAVA程序会在编译和运行的时候自动的检测可能出现的错误,而且它是一种强类型语言,对于类型的检查很严格,而且它的垃圾回收机制也有效的避免内存泄漏。2.为什么说java语言是完全面向对象的?(其实我觉得它...
  • Java:Garbage Collection

    2019-07-22 15:49:29
    GC是什么,描述一下GC的基本原理 垃圾回收器,内存处理时,不当的操作会使程序不稳定或者崩溃,当程序创建对象时,GC就开始监视这个对象的...GC会自动释放那些不需要的对象,以避免大部分的内存泄漏,但是仍然会有...
  • 2020秋招面经

    2019-10-13 16:56:54
    8月1号 pdd提前批 GC的理解 GC的理解,分代的好处 有GC还会有内存泄漏吗 堆内存和栈内存区别 classloader 什么样的资源会被认为可以被回收 设置堆的大小 stop the world的目的,能避免吗? ...
  •  内存泄漏,是指计算机可以分配的内存不够了,或者说内存被完全占满,新数据“溢出”。造成这种情况很简单,过大的数组,不断生成的线程等等。  异常可以说是不可避免的,错误是应该由程序员完全避免的。   ...
  • C++异常处理

    千次阅读 2019-01-23 11:34:06
    当动态申请了空间之后,在不需要这个空间的时候一定要释放,否则存在内存泄漏问题?那么我们怎么保证,自己申请的空间都被释放了呢?如果程序抛异常了,还可以保证吗? 什么是RAII?管理资源、避免内存泄露 构造函数...
  • RAII--智能指针

    2019-01-25 00:00:41
    当动态申请了空间之后,在不需要这个空间的时候一定要释放,否则存在内存泄漏问题?那么我们怎么保证,自己申请的空间都被释放了呢?如果程序抛异常了,还可以保证吗? 什么是RAII?管理资源、避免内存泄露 构造函数...
  • 重载和重写4.Java内存管理,垃圾回收5.Java内存泄漏,发生场景、原因、如何避免6.Java多线程,几种方式并分析使用场景7.Socket通信,tcp还是udp,步骤是什么8.算法题:一个数组每个元素都可以乘以任意个2,可不可以...
  • 这是享元模式就可以帮到我们了,使用享元模式我们可以达到对象共享,避免创建过多的对象,从而提升性能,避免内存泄漏等。 使用环境 存在大量相同的对象 需要缓冲池的场景 示例 就拿火车售票系统来说,如果...

空空如也

空空如也

1 2 3
收藏数 44
精华内容 17
关键字:

内存泄漏可以避免吗