此处将为大家介绍关于Python-解决内存泄漏的详细内容,并且为您解答有关python如何解决内存泄漏问题的相关问题,此外,我们还将为您介绍关于Android有效的解决内存泄漏的问题实例详解、c#–W
此处将为大家介绍关于Python-解决内存泄漏的详细内容,并且为您解答有关python如何解决内存泄漏问题的相关问题,此外,我们还将为您介绍关于Android 有效的解决内存泄漏的问题实例详解、c# – Web应用程序中IronPython内存泄漏的问题、EFcore多线程查询,该怎么解决内存泄漏的问题、ES6 通过 WeakMap 解决内存泄漏问题的有用信息。
本文目录一览:- Python-解决内存泄漏(python如何解决内存泄漏问题)
- Android 有效的解决内存泄漏的问题实例详解
- c# – Web应用程序中IronPython内存泄漏的问题
- EFcore多线程查询,该怎么解决内存泄漏的问题
- ES6 通过 WeakMap 解决内存泄漏问题
Python-解决内存泄漏(python如何解决内存泄漏问题)
我有一个Python程序,它运行一系列实验,没有打算从一个测试存储到另一个测试的数据。我的代码包含一个我完全找不到的内存泄漏(我已经查看了内存泄漏的其他线程)。由于时间限制,我不得不放弃寻找泄漏的机会,但是如果我能够隔离每个实验,该程序可能会运行足够长的时间以产生所需的结果。
- 在单独的线程中运行每个测试是否有帮助?
- 还有其他隔离泄漏影响的方法吗?
具体情况详
- 我的代码分为两部分:实验运行程序和实际实验代码。
- 尽管用于运行所有实验的代码与每个实验使用的代码之间没有共享全局变量,但某些类/函数必须共享。
- 实验运行程序不仅是简单的for循环,而且可以轻松地放入shell脚本中。它首先根据给定的配置参数来决定需要运行的测试,然后运行测试,然后以特定方式输出数据。
- 我尝试手动调用垃圾收集器,以防问题只是没有运行垃圾收集,但这没有用
更新资料
Gnibbler的答案实际上使我发现存储每次计算期间使用的 所有
数据的ClosenessCalculation对象没有被杀死。然后,我用它来手动删除一些似乎已解决内存问题的链接。
答案1
小编典典您可以使用类似的方法来帮助跟踪内存泄漏
>>> from collections import defaultdict>>> from gc import get_objects>>> before = defaultdict(int)>>> after = defaultdict(int)>>> for i in get_objects():... before[type(i)] += 1 ...
现在假设测试泄漏了一些内存
>>> leaked_things = [[x] for x in range(10)]>>> for i in get_objects():... after[type(i)] += 1... >>> print [(k, after[k] - before[k]) for k in after if after[k] - before[k]][(<type ''list''>, 11)]
11,因为我们泄漏了一个包含10个以上列表的列表
Android 有效的解决内存泄漏的问题实例详解
Android 有效的解决内存泄漏的问题
Android内存泄漏,我想做Android 应用的时候遇到的话很是头疼,这里是我在网上找的不错的资料,实例详解这个问题的解决方案
前言:最近在研究Handler的知识,其中涉及到一个问题,如何避免Handler带来的内存溢出问题。在网上找了很多资料,有很多都是互相抄的,没有实际的作用。
本文的内存泄漏检测工具是:LeakCanary github地址:https://github.com/square/leakcanary
什么是内存泄漏?
内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗。内存泄漏并不是指物理上的内存消失,这里的内存泄漏是值由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费。
怎样会导致内存泄漏?
资源对象没关闭造成的内存泄漏,如查询数据库后没有关闭游标cursor
构造Adapter时,没有使用 convertView 重用
Bitmap对象不在使用时调用recycle()释放内存
对象被生命周期长的对象引用,如activity被静态集合引用导致activity不能释放
内存泄漏有什么危害?
内存泄漏对于app没有直接的危害,即使app有发生内存泄漏的情况,也不一定会引起app崩溃,但是会增加app内存的占用。内存得不到释放,慢慢的会造成app内存溢出。所以我们解决内存泄漏的目的就是防止app发生内存溢出。
1、新建线程引起的Activity内存泄漏
例子:
package rxnet.zyj.com.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class Activity6 extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_6); findViewById( R.id.finish).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); new Thread(new Runnable() { @Override public void run() { try {<br> //模拟耗时操作 Thread.sleep( 15000 ); } catch (InterruptedException e) { e.printstacktrace(); } } }).start(); } }
运行上面的代码后,点击finish按钮,过一会儿发生了内存泄漏的问题。
为什么Activity6会发生内存泄漏?
进入Activity6 界面,然后点击finish按钮,Activity6销毁,但是Activity6里面的线程还在运行,匿名内部类Runnable对象引用了Activity6的实例,导致Activity6所占用的内存不能被GC及时回收。
如何改进?
Runnable改为静态非匿名内部类即可。
package rxnet.zyj.com.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class Activity6 extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_6); findViewById( R.id.finish).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); new Thread( new MyRunnable()).start(); } private static class MyRunnable implements Runnable { @Override public void run() { try { Thread.sleep( 15000 ); } catch (InterruptedException e) { e.printstacktrace(); } } } }
2、Activity添加监听器造成Activity内存泄漏
package rxnet.zyj.com.myapplication; import android.app.Activity; import android.os.Bundle; public class LeakActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NastyManager.getInstance().addListener(this); } }
这个是在开发中经常会犯的错误,NastyManager.getInstance() 是一个单例,当我们通过 addListener(this) 将 Activity 作为 Listener 和 NastyManager 绑定起来的时候,不好的事情就发生了。
如何改进?
想要修复这样的 Bug,其实相当简单,就是在你的 Acitivity 被销毁的时候,将他和 NastyManager 取消掉绑定就好了。
package rxnet.zyj.com.myapplication; import android.app.Activity; import android.os.Bundle; public class LeakActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NastyManager.getInstance().addListener(this); } @Override protected void onDestroy() { super.onDestroy(); NastyManager.getInstance().removeListener(this); } }
3、Handler 匿名内部类造成内存溢出?
先看着一段代码
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; public class HandlerActivity extends AppCompatActivity { private final static int MESSAGECODE = 1 ; private final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("mmmmmmmm","handler " + msg.what ) ; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); findViewById( R.id.finish ).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); new Thread(new Runnable() { @Override public void run() { handler.sendEmptyMessage( MESSAGECODE ) ; try { Thread.sleep( 8000 ); } catch (InterruptedException e) { e.printstacktrace(); } handler.sendEmptyMessage( MESSAGECODE ) ; } }).start() ; } }
这段代码运行起来后,立即点击 finish 按钮,通过检测,发现 HandlerActivity 出现了内存泄漏。当Activity finish后,延时消息会继续存在主线程消息队列中8秒钟,然后处理消息。而该消息引用了Activity的Handler对象,然后这个Handler又引用了这个Activity。这些引用对象会保持到该消息被处理完,这样就导致该Activity对象无法被回收,从而导致了上面说的 Activity泄露。Handler 是个很常用也很有用的类,异步,线程安全等等。如果有下面这样的代码,会发生什么呢? handler.postDeslayed ,假设 delay 时间是几个小时… 这意味着什么?意味着只要 handler 的消息还没有被处理结束,它就一直存活着,包含它的 Activity 就跟着活着。我们来想办法修复它,修复的方案是 WeakReference ,也就是所谓的弱引用。垃圾回收器在回收的时候,是会忽视掉弱引用的,所以包含它的 Activity 会被正常清理掉。
如何避免
使用静态内部类
使用弱引用
修改后代码是这样的。
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import java.lang.ref.WeakReference; public class HandlerActivity extends AppCompatActivity { private final static int MESSAGECODE = 1 ; private static Handler handler ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); findViewById( R.id.finish ).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); handler = new MyHandler( this ) ; new Thread(new Runnable() { @Override public void run() { handler.sendEmptyMessage( MESSAGECODE ) ; try { Thread.sleep( 8000 ); } catch (InterruptedException e) { e.printstacktrace(); } handler.sendEmptyMessage( MESSAGECODE ) ; } }).start() ; } private static class MyHandler extends Handler { WeakReference<HandlerActivity> weakReference ; public MyHandler(HandlerActivity activity ){ weakReference = new WeakReference<HandlerActivity>( activity) ; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( weakReference.get() != null ){ // update android ui Log.d("mmmmmmmm","handler " + msg.what ) ; } } } }
这个Handler已经使用了静态内部类,并且使用了弱引用。但是这个并没有完全解决 HandlerActivity 内存泄漏的问题,罪魁祸首是线程创建的方式出了问题,就像本文的第一个例子一样。改进的方式,是把Runnable类写成静态内部类。
最终完整的代码如下:
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import java.lang.ref.WeakReference; public class HandlerActivity extends AppCompatActivity { private final static int MESSAGECODE = 1 ; private static Handler handler ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); findViewById( R.id.finish ).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //创建Handler handler = new MyHandler( this ) ; //创建线程并且启动线程 new Thread( new MyRunnable() ).start(); } private static class MyHandler extends Handler { WeakReference<HandlerActivity> weakReference ; public MyHandler(HandlerActivity activity ){ weakReference = new WeakReference<HandlerActivity>( activity) ; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( weakReference.get() != null ){ // update android ui Log.d("mmmmmmmm","handler " + msg.what ) ; } } } private static class MyRunnable implements Runnable { @Override public void run() { handler.sendEmptyMessage( MESSAGECODE ) ; try { Thread.sleep( 8000 ); } catch (InterruptedException e) { e.printstacktrace(); } handler.sendEmptyMessage( MESSAGECODE ) ; } } }
等等,还没完呢?
上面这个代码已经有效的解决了Handler,Runnable 引用Activity实例从而导致内存泄漏的问题,但是这不够。因为内存泄漏的核心原因就是这个某个对象应该被系统回收内存的时候,却被其他对象引用,造成该内存无法回收。所以我们在写代码的时候,要始终绷着这个弦。再回到上面这个问题,当当前Activity调用finish销毁的时候,在这个Activity里面所有线程是不是应该在OnDestory()方法里,取消线程。当然是否取消异步任务,要看项目具体的需求,比如在Activity销毁的时候,启动一个线程,异步写log日志到本地磁盘,针对这个需求却需要在OnDestory()方法里开启线程。所以根据当前环境做出选择才是正解。
所以我们还可以修改代码为:在onDestroy() 里面移除所有的callback 和 Message 。
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import java.lang.ref.WeakReference; public class HandlerActivity extends AppCompatActivity { private final static int MESSAGECODE = 1 ; private static Handler handler ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); findViewById( R.id.finish ).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //创建Handler handler = new MyHandler( this ) ; //创建线程并且启动线程 new Thread( new MyRunnable() ).start(); } private static class MyHandler extends Handler { WeakReference<HandlerActivity> weakReference ; public MyHandler(HandlerActivity activity ){ weakReference = new WeakReference<HandlerActivity>( activity) ; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( weakReference.get() != null ){ // update android ui Log.d("mmmmmmmm","handler " + msg.what ) ; } } } private static class MyRunnable implements Runnable { @Override public void run() { handler.sendEmptyMessage( MESSAGECODE ) ; try { Thread.sleep( 8000 ); } catch (InterruptedException e) { e.printstacktrace(); } handler.sendEmptyMessage( MESSAGECODE ) ; } } @Override protected void onDestroy() { super.onDestroy(); //如果参数为null的话,会将所有的Callbacks和Messages全部清除掉。 handler.removeCallbacksAndMessages( null ); } }
4、AsyncTask造成内存泄漏
package rxnet.zyj.com.myapplication; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; public class Activity2 extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_2); findViewById( R.id.finish2).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); new AsyncTask<String,Integer,String>(){ @Override protected String doInBackground(String... params) { try { Thread.sleep( 6000 ); } catch (InterruptedException e) { } return "ssss"; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); Log.d( "mmmmmm activity2 ","" + s ) ; } }.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR,"" ) ; } }
为什么?
上面代码在activity中创建了一个匿名类AsyncTask,匿名类和非静态内部类相同,会持有外部类对象,这里也就是activity,因此如果你在Activity里声明且实例化一个匿名的AsyncTask对象,则可能会发生内存泄漏,如果这个线程在Activity销毁后还一直在后台执行,那这个线程会继续持有这个Activity的引用从而不会被GC回收,直到线程执行完成。
怎么解决?
自定义静态AsyncTask类A
syncTask的周期和Activity周期保持一致。也就是在Activity生命周期结束时要将AsyncTask cancel掉。
package rxnet.zyj.com.myapplication; import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class AsyncTaskActivity extends AppCompatActivity { private static MyTask myTask ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_asynctask); findViewById( R.id.finish).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); myTask = new MyTask() ; myTask.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR,"") ; } private static class MyTask extends AsyncTask{ @Override protected Object doInBackground(Object[] params) { try { //模拟耗时操作 Thread.sleep( 15000 ); } catch (InterruptedException e) { e.printstacktrace(); } return ""; } } @Override protected void onDestroy() { super.onDestroy(); //取消异步任务 if ( myTask != null ){ myTask.cancel(true ) ; } } }
5、Timer Tasks 造成内存泄漏
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import java.util.Timer; import java.util.TimerTask; public class TimerActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_2); findViewById( R.id.finish2).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //开始定时任务 timer(); } void timer(){ new Timer().schedule(new TimerTask() { @Override public void run() { while(true); } },1000 ); // 1秒后启动一个任务 } }
为什么?
这里内存泄漏在于Timer和TimerTask没有进行Cancel,从而导致Timer和TimerTask一直引用外部类Activity。
怎么解决?
在适当的时机进行Cancel。
TimerTask用静态内部类
注意:在网上看到一些资料说,解决TimerTask内存泄漏可以使用在适当的时机进行Cancel。经过测试,证明单单使用在适当的时机进行Cancel , 还是有内存泄漏的问题。所以一定要用静态内部类配合使用。
package rxnet.zyj.com.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import java.util.Timer; import java.util.TimerTask; public class TimerActivity extends AppCompatActivity { private TimerTask timerTask ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_2); findViewById( R.id.finish2).setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); //开始定时任务 timer(); } void timer(){ timerTask = new MyTimerTask() ; new Timer().schedule( timerTask,1000 ); // 1秒后启动一个任务 } private static class MyTimerTask extends TimerTask{ @Override public void run() { while(true){ Log.d( "ttttttttt","timerTask" ) ; } } } @Override protected void onDestroy() { super.onDestroy(); //取消定时任务 if ( timerTask != null ){ timerTask.cancel() ; } } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
c# – Web应用程序中IronPython内存泄漏的问题
第一个问题,我实际上并没有运行任何特定于IronPython的脚本,我正在实现Pygments库,因此我可以获得服务器端语法突出显示.该库大约有20个文件.
除了最新的IronPython版本无法将脚本编译成DLL(由于this issue)之外,我确实通过将所有文件和依赖项复制到我的bin文件夹来成功运行.
问题是,我去看看我的w3wp.exe进程在进行突出显示时是如何做的,并注意到一些showstopper问题:
>即使在Cassini下的一个完全基本的空网站中,使用sql词法分析器突出显示代码* from table会导致每次执行时跳过10MB(页面刷新)…我明确关闭引擎并使用LightweightScopes在单个函数调用中.它从大约30MB开始,大约20次刷新,大约150MB左右.
>在我的实际Web应用程序中,使用sql词法分析器(相同的代码)会导致我的应用程序池增加大约200MB /秒(字面意思是,当它达到大约1GB时我会将其杀死),直到它崩溃w3wp或者减慢我的PC速度到爬行.这在空的测试站点中不会发生,并且在具有相同确切代码的控制台应用程序中完全没有问题.像C#这样的其他词法分析器不会导致巨大的内存泄漏,但每次调用该函数时都会产生相同的增加内存的效果.
这使我相信这是一个特定于Web的问题,考虑到控制台应用程序没有任何问题(实例化运行时确实会导致内存增加20MB).
我正在使用2.7 IPY版本和1.4版本的Pygments.
我目前没有确切的代码,但它看起来像:
var options = something; options["LightweightScopes"] = ScriptRuntimeHelpers.True; // from another SO post,'true' didn't seem to work var engine = Python.CreateEngine(options); // // set up search paths here... // dynamic scope = whatever; ScriptSource source = engine.CreateScriptSourceFromFile("myscript.py"); // Execute? Compile? It populates the scope at this point... source.Compile(scope); // execute (code,lexer name,style) // this is a python function I have that calls the Pygments code var highlighted = scope.generate_html("select * from table","sql","monokai"); engine.Shutdown(); return highlighted;
就像我说的,我将相同的代码复制到:a)控制台应用程序,b)全新的空网络应用程序,c)我的原始网络应用程序.控制台应用程序没有泄漏内存,但网络应用程序.
我还使用本机Python(python myscript.py)和IPY(ipy myscript.py)执行该函数,并且没有任何内存泄漏.
处理运行时是否缺少一些最佳实践?我计划在共享环境中运行它,因此在不同的应用程序池中实例化引擎的可能解决方法可能对我不起作用(同样,200MB / s的巨大泄漏也是一种显示).
目前,除非某人有奇迹治疗,否则我打算废弃我的代码,并使用Javascript语法荧光笔.真的很不幸,因为Pygments很棒……
解决方法
如果你真的在泄漏记忆,那么你就会持续太长时间.回顾你Idisposables(特别是列表理解可能会受到伤害,特别是对于Linqy这样的命令和明确的修改).
我曾经使应用程序运行速度提高了2倍,当它通过在最大的枚举上添加一个简单的.ToList()来驱逐一个大进程时,通过耗尽/分段堆而可靠地失败.
.NET有很好的内存分析器,但我目前知道如何只运行mono -profiler(坏内存).一个简单的谷歌将帮助您找到您可以在您的环境中使用的探查器:让它准确地告诉您哪些对象分配在哪里碎片堆
PS.因为我看到你在第二次扫描你的问题时指着Web应用程序,我会补充:检查从会话状态(应用程序,会话)保持什么引用(间接).
EFcore多线程查询,该怎么解决内存泄漏的问题
昨天在园子里提了一个EFcore多线程查询导致服务内存飙升的问题,现在依然还没有找到解决办法,今天把问题详细的陈述一遍。
刚开始发现问题是公司一个服务的内存飚到了7个G,系统直接杀死了这个进程,后面发现问题是随着高并发的访问,里面的EFcore进行大量数据查询,在访问结束后内存没有释放干净,内存不断的堆积,服务直接就崩了。然后我在本地用例还原了这个过程,大致如下:
GRPC服务端:
(一开始怀疑是DatabaseContext注入的问题,用了AddScoped;AddTransient;后者直接用using都没有解决问题,所以不是这个问题)
在GRPC里一个方法SayHello查询一张表的数据(数据大概1w多)
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
var d = efoscoreContext.Project.Where(w => w.ProjectId > 15).Select(s => new
{
*******
}).ToList();
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
客户端:
每三秒调一次Grpc的SayHello方法,后面发现GRPC服务里确实释放不完内存,随着访问的次数的增加,内存会堆积到一个很高的值,如果内存抗不住就崩了
while (true)
{
for (int i = 1; i < 40; i++)
{
reply = client.SayHello(new FirstGrpc.HelloRequest() { Name = "" });
}
Thread.Sleep(TimeSpan.FromSeconds(3));
}
过程会进行GC,但是还会剩下大量的内存没GC完,而且会累积到很高。
后面思考,GRPC服务以线程池的方式响应请求,会不会是Efcore在多线程里出现了问题的原因
后面我用控制台做了一个测试,发现问题确实是这样,Efocore在多线程查询,线程结束后,内存并没有回收完
多线程Efocore查询用例:
先顺序执行:
while (true)
{
for (int i = 1; i < 100; i++)
{
ProjectQuery()//执行efocore查询
;
}
Thread.Sleep(TimeSpan.FromSeconds(5));
}
顺序执行没有任何问题,内存占用是很正常的也就一直100多M
多线程执行:
while (true)
{
for (int i = 1; i < 100; i++)
{
var t = new Task(() => ProjectQuery()//执行efocore查询
);
t.Start();
}
Thread.Sleep(TimeSpan.FromSeconds(5));
}
多线程执行一上来就飚到了2G,后面会剩下1.2g一直在那里,再后面就会1-4M的累积,累积
ES6 通过 WeakMap 解决内存泄漏问题
一、Map
1. 定义
Map 对象保存键值对,类似于数据结构字典;与传统上的对象只能用字符串当键不同,Map 对象可以使用任意值当键。
2. 语法
new Map([iterable])
属性
- size:返回键值对的数量。
操作方法
- set (key, value):设置(新增 / 更新)键 key 的值为 value,返回 Map 对象。
- get (key):读取键 key 的值,没有则返回 undefined。
- has (key):判断一个 Map 对象中是否存在某个键值对,返回 true/false。
- delete (key):删除某个键值对,返回 true/false。
- clear ():清除 Map 对象中所有键值对。
遍历方法
- keys ():返回键名的 Iterator 对象。
- values ():返回键值的 Iterator 对象。
- entries ():返回键值对的 Iterator 对象。
- forEach ((value, key, map) => {}):遍历 Map 对象所有键值对。
3. 示例
操作方法
let m = new Map([
[''foo'', 11],
[''bar'', 22]
]);
m.set(''mazey'', 322)
.set(''mazey'', 413);
console.log(m); // {"foo" => 11, "bar" => 22, "mazey" => 413}
console.log(m.has(''mazey'')); // true
m.delete(''mazey'');
console.log(m.has(''mazey'')); // false
m.clear();
console.log(m); // {}
遍历方法
let m = new Map([
[''foo'', 11],
[''bar'', 22],
[''mazey'', 413]
]);
console.log(m); // {"foo" => 11, "bar" => 22, "mazey" => 413}
console.log(m.keys()); // MapIterator {"foo", "bar", "mazey"}
console.log(m.values()); // MapIterator {11, 22, 413}
console.log(m.entries()); // MapIterator {"foo" => 11, "bar" => 22, "mazey" => 413}
m.forEach((value, key, map) => {
console.log("键:%s,值:%s", key, value);
});
// 键:foo,值:11
// 键:bar,值:22
// 键:mazey,值:413
二、WeakMap
1. 定义
WeakMap 对象保存键值对,与 Map 不同的是其键必须是对象,因为键是弱引用,在键对象消失后自动释放内存。
2. 语法
new WeakMap([iterable])
方法
- set (key, value):设置(新增 / 更新)键 key 的值为 value,返回 WeakMap 对象。
- get (key):读取键 key 的值,没有则返回 undefined。
- has (key):判断一个 WeakMap 对象中是否存在某个键值对,返回 true/false。
- delete (key):删除某个键值对,返回 true/false。
注意
因为 WeakMap 的特殊的垃圾回收机制,所以没有 clear () 方法。
3. 示例
let obj = {
foo: 11
};
let wm = new WeakMap();
wm.set(obj, 413322);
console.log(wm); // {{…} => 413322}
console.log(wm.has(obj)); // true
三、通过 WeakMap 解决内存泄漏问题
当使用 Dom 对象绑定事件时,Dom 对象消失后若没有及时释放内存(置 null),便会一直存在内存中。 使用 WeakMap 保存 Dom 对象不会出现这样的问题,因为 Dom 对象消失后,JS 的垃圾回收机制便会自动释放其所占用的内存。
<button type="button" id="btn">按钮</button>
<script>
let wm = new WeakMap();
let btn = document.querySelector(''#btn'');
wm.set(btn, {count: 0});
btn.addEventListener(''click'', () => {
let v = wm.get(btn);
v.count++;
console.log(wm.get(btn).count);
});
// 1 2 3 4 5...
</script>
ES6 通过 WeakMap 解决内存泄漏问题
关于Python-解决内存泄漏和python如何解决内存泄漏问题的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android 有效的解决内存泄漏的问题实例详解、c# – Web应用程序中IronPython内存泄漏的问题、EFcore多线程查询,该怎么解决内存泄漏的问题、ES6 通过 WeakMap 解决内存泄漏问题等相关知识的信息别忘了在本站进行查找喔。
本文标签: