- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Activity
用ConstraingLayout
有很多 ImageView
s(每张卡一张)。
获胜后,通过单击将出现的 ImageView,Activity
将被“重新加载”,显示一组新的牌来玩。
问题是每次获胜后 Activity
使用的内存提高而不是返回初始使用的金额。
这会导致 OutOfMemory Exception
在一些内存不足的设备上(例如在 Nexus 7 上)。 :(
逻辑是:
onCreate
方法我设置 ConstraintLayout
由 30 ImageView
制成s(卡片正面)等 30 ImageView
s(卡片背面)ImageView
(正面和背面)我设置了 OnClickListener
和图像通过缩放可绘制资源ImageView
, 我将卡片两侧的 alpha 设置为只显示正确的一面GiocaMemory.java:
package ...
import ...
public class GiocaMemory extends AppCompatActivity
{
...
MediaPlayer mediaPlayer;
MediaPlayer.OnCompletionListener onCompletionListenerReleaseMediaPlayer;
private AudioManager audioManager;
private AudioManager.OnAudioFocusChangeListener onAudioFocusChangeListener;
...
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
...
onCompletionListenerReleaseMediaPlayer = new MediaPlayer.OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer mp)
{
releaseMediaPlayer();
}
};
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
onAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener()
{
@Override
public void onAudioFocusChange(int focusChange)
{
if(mediaPlayer != null)
{
switch (focusChange)
{
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
mediaPlayer.pause();
mediaPlayer.seekTo(0);
break;
case AudioManager.AUDIOFOCUS_GAIN:
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
mediaPlayer.start();
break;
case AudioManager.AUDIOFOCUS_LOSS:
releaseMediaPlayer();
break;
}
}
}
};
...
}
private void win()
{
showView(textViewWin);
}
public void reloadActivity()
{
finish();
startActivity(getIntent());
}
public void playSound(int idElement)
{
String name = idElement + "_name";
playAudio(name, onCompletionListenerReleaseMediaPlayer);
}
public void playAudioName(int idElement)
{
String name = idElement + "_sound";
playAudio(name, onCompletionListenerReleaseMediaPlayer);
}
public void onClickHome(View view)
{
finish();
}
public void stopAudio()
{
releaseMediaPlayer();
}
private void playAudio(String audioName, MediaPlayer.OnCompletionListener onCompletionListener)
{
stopAudio();
if(!audioName.isEmpty())
{
int result = audioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
{
int resID = res.getIdentifier(audioName, "raw", getPackageName());
if (resID == 0)
{
return;
}
releaseMediaPlayer();
startMediaPlayerWithRes(this, resID, audioName);
mediaPlayer.setOnCompletionListener(onCompletionListener);
}
}
}
private void startMediaPlayerWithRes(Context context, int resID, String audioName)
{
mediaPlayer = MediaPlayer.create(context, resID);
if(mediaPlayer != null) mediaPlayer.start();
else mediaPlayer = new MediaPlayer();
}
private void releaseMediaPlayer()
{
if(mediaPlayer != null) mediaPlayer.release();
mediaPlayer = null;
}
private void loadContents()
{
...
}
@Override
protected void onPause()
{
super.onPause();
releaseMediaPlayer();
}
public void freeRes()
{
...
mediaPlayer = null;
onCompletionListenerReleaseMediaPlayer = null;
audioManager = null;
onAudioFocusChangeListener = null;
res = null;
releaseMediaPlayer();
}
@Override
protected void onDestroy() {
super.onDestroy();
freeRes();
}
}
第一次运行 GiocaMemory
AndroidStudio
的 profiler
是:
获胜后(即第二次 onCreate
之后)使用的内存为:
现在 Java
内存使用量为 28,1 MB
, 而不是返回初始值 25,2 MB
.
屏幕截图引用了 16 个框的布局。 在 30 盒布局中,使用的内存增加了很多。 (例如从 49 MB 到 83 MB)
我可能会说图像的大小调整得足够多,以便尽可能使用更少的内存,所以也许它们不是问题所在。如果我错了请告诉我。
Java
使用的 MB会增加吗?GiocaMemory
的方式 Activity 是正确的还是有其他方式可以让我释放更多资源?我发现很难找到它们,因为我对 Android 编程还比较陌生,尤其是因为我几乎从来没有遇到过与内存使用过多相关的问题。
编辑:
这些是使用 LeakCanary 的一些信息:
通过单击 3 个“GiocaMemory Leaked 21 Agosto 13:35”之一(所有 3 个都相同,仅更改跟踪末尾的 key =
)
ApplicationLeak(className=app.myapp.GiocaMemory, leakTrace=
┬
├─ android.media.AudioManager$1
│ Leaking: UNKNOWN
│ Anonymous subclass of android.media.IAudioFocusDispatcher$Stub
│ GC Root: Global variable in native code
│ ↓ AudioManager$1.this$0
│ ~~~~~~
├─ android.media.AudioManager
│ Leaking: UNKNOWN
│ ↓ AudioManager.mAudioFocusIdListenerMap
│ ~~~~~~~~~~~~~~~~~~~~~~~~
├─ java.util.HashMap
│ Leaking: UNKNOWN
│ ↓ HashMap.table
│ ~~~~~
├─ java.util.HashMap$HashMapEntry[]
│ Leaking: UNKNOWN
│ ↓ array HashMap$HashMapEntry[].[0]
│ ~~~
├─ java.util.HashMap$HashMapEntry
│ Leaking: UNKNOWN
│ ↓ HashMap$HashMapEntry.value
│ ~~~~~
├─ app.myapp.GiocaMemory$2
│ Leaking: UNKNOWN
│ Anonymous class implementing android.media.AudioManager$OnAudioFocusChangeListener
│ ↓ GiocaMemory$2.this$0
│ ~~~~~~
╰→ app.myapp.GiocaMemory
Leaking: YES (Activity#mDestroyed is true and ObjectWatcher was watching this)
key = dfa0d5fe-0c50-4c64-a399-b5540eb686df
watchDurationMillis = 380430
retainedDurationMillis = 375425
, retainedHeapByteSize=470627)
official LeakCanary's documentation说:
If a node is not leaking, then any prior reference that points to it is not the source of the leak, and also not leaking. Similarly, if a node is leaking then any node down the leak trace is also leaking. From that, we can deduce that the leak is caused by a reference that is after the last
Leaking: NO
and before the firstLeaking: YES
.
但在我的 leakTrace 中只有 UNKNOWN
除了最后一次泄漏 YES
.
我怎样才能找到 YES
在我的代码中泄漏,如果它可能是泄漏?
非常感谢您的帮助!
最佳答案
您是否正确地放弃了 AudioManager 中的焦点监听器?
AudioManager#abandonAudioFocus(OnAudioFocusChangeListener 监听器)
实际的 OOM 可能是上述非回收列表的结果,但这可能是内存泄漏的原因。
关于java - 在 Activity 代码中查找内存泄漏以释放内存使用并避免 OutOfMemory Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57462677/
我尝试理解[c代码 -> 汇编]代码 void node::Check( data & _data1, vector& _data2) { -> push ebp -> mov ebp,esp ->
我需要在当前表单(代码)的上下文中运行文本文件中的代码。其中一项要求是让代码创建新控件并将其添加到当前窗体。 例如,在Form1.cs中: using System.Windows.Forms; ..
我有此 C++ 代码并将其转换为 C# (.net Framework 4) 代码。有没有人给我一些关于 malloc、free 和 sprintf 方法的提示? int monate = ee; d
我的网络服务器代码有问题 #include #include #include #include #include #include #include int
给定以下 html 代码,将列表中的第三个元素(即“美丽”一词)以斜体显示的 CSS 代码是什么?当然,我可以给这个元素一个 id 或一个 class,但 html 代码必须保持不变。谢谢
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我试图制作一个宏来避免重复代码和注释。 我试过这个: #define GrowOnPage(any Page, any Component) Component.Width := Page.Surfa
我正在尝试将我的旧 C++ 代码“翻译”成头条新闻所暗示的 C# 代码。问题是我是 C# 中的新手,并不是所有的东西都像 C++ 中那样。在 C++ 中这些解决方案运行良好,但在 C# 中只是不能。我
在 Windows 10 上工作,R 语言的格式化程序似乎没有在 Visual Studio Code 中完成它的工作。我试过R support for Visual Studio Code和 R-T
我正在处理一些报告(计数),我必须获取不同参数的计数。非常简单但乏味。 一个参数的示例查询: qCountsEmployee = ( "select count(*) from %s wher
最近几天我尝试从 d00m 调试网络错误。我开始用尽想法/线索,我希望其他 SO 用户拥有可能有用的宝贵经验。我希望能够提供所有相关信息,但我个人无法控制服务器环境。 整个事情始于用户注意到我们应用程
我有一个 app.js 文件,其中包含如下 dojo amd 模式代码: require(["dojo/dom", ..], function(dom){ dom.byId('someId').i
我对“-gencode”语句中的“code=sm_X”选项有点困惑。 一个例子:NVCC 编译器选项有什么作用 -gencode arch=compute_13,code=sm_13 嵌入库中? 只有
我为我的表格使用 X-editable 框架。 但是我有一些问题。 $(document).ready(function() { $('.access').editable({
我一直在通过本教程学习 flask/python http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-wo
我想将 Vim 和 EMACS 用于 CNC、G 代码和 M 代码。 Vim 或 EMACS 是否有任何语法或模式来处理这种类型的代码? 最佳答案 一些快速搜索使我找到了 this vim 和 thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve this
这个问题在这里已经有了答案: Enabling markdown highlighting in Vim (5 个回答) 6年前关闭。 当我在 Vim 中编辑包含 Markdown 代码的 READM
我正在 Swift3 iOS 中开发视频应用程序。基本上我必须将视频 Assets 和音频与淡入淡出效果合并为一个并将其保存到 iPhone 画廊。为此,我使用以下方法: private func d
pipeline { agent any stages { stage('Build') { steps { e
我是一名优秀的程序员,十分优秀!