等待 Android studio 日志中的阻塞 GC 分配
Waiting for a blocking GC Alloc in Android studio logs
我有一个相当大的双数组,例如 1,71,00,000 个元素。我需要遍历数组,将数组切片为每个 10k 点的较小数组,并将剩余的点(如果有)切入最后一个切片。
我有一个基本代码:
public static boolean getSliceOfArray(double[] arr,int slice_len)
{
//arr: big array
//slice_len: 10,000
System.out.println(arr.length);
int n_times=(arr.length/slice_len);
int i=0;
for(int n=0;n<n_times;n++)
{
Arrays.copyOfRange(arr,i,i+slice_len);
i=i+slice_len;
}
System.out.println(n_times);
if(i!=arr.length)
{
System.out.println( Arrays.copyOfRange(arr,i,arr.length).length);
}
return true;
}
它给我以下输出:
I/System.out: 17100000
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 13.428ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 36.867ms
I/xample.styleap: Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 26.012ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 32.625ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 21.645ms
Starting a blocking GC Alloc
I/System.out: 1710
当我对相当小的数组执行相同操作时,输出不是这样的。为什么会显示“Waiting for a blocking GC Alloc”和这些消息?这是一个严重的问题吗? JVM 问题还是我的逻辑错误?
在我的 manifest.xml 中使用 android:largeHeap="true"
解决了这个问题。
您的应用程序使用了过多的堆内存(可能动态创建对象而没有收集垃圾),因此 Java GC 不断尝试释放内存,但它无法做到它因为您的应用程序正在产生大量“泄漏”。所以基本上你的应用程序内存需求不断增加,因此 GC 会警告你它最终会导致崩溃
你应该:
- 使用Android Studio Memory Profiler 分析内存分配
- 分析堆转储
- 检查内存泄漏(原因之一可能是静态变量太多!)
System.gc() (正如之前有人建议的那样)不会有帮助,因为你不能 guarantee/force GC
我建议先 improve/edit 您自己的代码库,而不是使用标志来增加 JVM args 中的堆大小。
我有一个相当大的双数组,例如 1,71,00,000 个元素。我需要遍历数组,将数组切片为每个 10k 点的较小数组,并将剩余的点(如果有)切入最后一个切片。
我有一个基本代码:
public static boolean getSliceOfArray(double[] arr,int slice_len)
{
//arr: big array
//slice_len: 10,000
System.out.println(arr.length);
int n_times=(arr.length/slice_len);
int i=0;
for(int n=0;n<n_times;n++)
{
Arrays.copyOfRange(arr,i,i+slice_len);
i=i+slice_len;
}
System.out.println(n_times);
if(i!=arr.length)
{
System.out.println( Arrays.copyOfRange(arr,i,arr.length).length);
}
return true;
}
它给我以下输出:
I/System.out: 17100000
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 13.428ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 36.867ms
I/xample.styleap: Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 26.012ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 32.625ms
Starting a blocking GC Alloc
I/xample.styleap: Waiting for a blocking GC Alloc
I/xample.styleap: WaitForGcToComplete blocked Alloc on HeapTrim for 21.645ms
Starting a blocking GC Alloc
I/System.out: 1710
当我对相当小的数组执行相同操作时,输出不是这样的。为什么会显示“Waiting for a blocking GC Alloc”和这些消息?这是一个严重的问题吗? JVM 问题还是我的逻辑错误?
在我的 manifest.xml 中使用 android:largeHeap="true"
解决了这个问题。
您的应用程序使用了过多的堆内存(可能动态创建对象而没有收集垃圾),因此 Java GC 不断尝试释放内存,但它无法做到它因为您的应用程序正在产生大量“泄漏”。所以基本上你的应用程序内存需求不断增加,因此 GC 会警告你它最终会导致崩溃
你应该:
- 使用Android Studio Memory Profiler 分析内存分配
- 分析堆转储
- 检查内存泄漏(原因之一可能是静态变量太多!)
System.gc() (正如之前有人建议的那样)不会有帮助,因为你不能 guarantee/force GC
我建议先 improve/edit 您自己的代码库,而不是使用标志来增加 JVM args 中的堆大小。