2012-12-12 102 views
1

我正在开发一个简单的pdf阅读器重写一个现有的例子。 我的应用程序有一个自定义视图,其中有两个按钮,前后都是。当点击下一个按钮时,它会从互联网上下载pdf并在视图中显示。每次单击下一个或上一个按钮时,将调用以下showPdf()方法。Android/Java对象没有垃圾回收

public void showPdf(){ 

    RelativeLayout lout = (RelativeLayout)LayoutInflater.from(this).inflate(R.layout.main, null); 
setContentView(lout); 
m_vPDF = null; 
m_vPDF = (PDFReader)lout.findViewById(R.id.PDFView); 

m_vPDF.open(m_doc); 


m_vPDF.setViewListener(m_vPDF); 

LinearLayout bar_find = (LinearLayout)lout.findViewById(R.id.bar_find); 
    // 
btn_prev = (Button)bar_find.findViewById(R.id.btn_prev); 
btn_next = (Button)bar_find.findViewById(R.id.btn_next); 
//   
btn_prev.setOnClickListener(this); 
btn_next.setOnClickListener(this); 
} 

PDFReader是具有查看器显示PDF的对象。以下是PDFReader代码的一部分。

public class PDFReader extends View implements PDFView.PDFViewListener, 

    ThumbView.ThumbListener 
{ 

private PDFView m_viewer = null; 

public PDFReader(Context context) 
{ 
    super(context); 
} 
public PDFReader(Context context, AttributeSet attrs) 
{ 
    super(context, attrs); 
} 
public void set_viewer(int view_style) 
{ 

    switch(view_style) 
    { 
    case 1: 
     m_viewer = new PDFViewHorz(); 
     break; 
    case 2: 
     m_viewer = new PDFViewScroll(); 
     break; 
    case 3: 
     m_viewer = new PDFViewSingle(); 
     break; 
    case 4: 
     m_viewer = new PDFViewSingleEx(); 
     break; 
    case 5: 
     m_viewer = new PDFViewReflow(); 
     break; 
    default: 
     m_viewer = new PDFViewVert(); 
     break; 
    } 
    if(m_viewer != null) 
    { 
     if(doc != null) m_viewer.viewOpen(getContext(), doc, 0xFFCC0000, 4); 
     m_viewer.viewSetAnnotListener(annot_listener); 
     m_viewer.viewSetViewListener(view_listener); 
     m_viewer.viewResize(getWidth(), getHeight()); 
     if(pos != null) m_viewer.viewGoto(pos); 
    } 
} 

在我showPdf我PDFReader一个按钮被点击,每次初始化和内部PDFReader如果设置PDFReader为null,PDFView为null PDFView实例初始化甚至收集PDFViewVert对象,从来没有垃圾。 因此导致了内存异常。

这是转储的内存分析,显示了14个PDFViewVert实例已经创建并且从未被释放。

14 instances of "com.radaee.pdfex.PDFViewVert$1", loaded by "dalvik.system.PathClassLoader @ 0x412a0b08" occupy 19,602,792 (64.39%) bytes. 

Biggest instances: 

com.radaee.pdfex.PDFViewVert$1 @ 0x412a1ae8 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x412c7c30 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x418bdf78 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x41a382f8 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x41a4df50 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x41eaf1c0 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x4202a8e0 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x421aaa10 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x4233dbf8 - 1,543,040 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x412a0bf0 - 1,543,024 (5.07%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x412bbf58 - 1,390,792 (4.57%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x412f0790 - 1,390,792 (4.57%) bytes. 
com.radaee.pdfex.PDFViewVert$1 @ 0x424c4b50 - 1,390,792 (4.57%) bytes. 


Keywords 
com.radaee.pdfex.PDFViewVert$1 
dalvik.system.PathClassLoader @ 0x412a0b08 

任何帮助表示赞赏.. 谢谢,

+0

我的答案可以帮助你解决你的问题吗? –

回答

1

尝试这样的:

Runtime.getRuntime().gc(); 

更改此

m_vPDF = null; 

要,

if (m_vPDF != null){ 
    m_vPDF.recycle(); 
    m_vPDF = null; 
} 

这将可以帮助你清理未使用的对象。

希望它可以帮助你。

谢谢。

+0

代码中的哪个位置是进行此调用的最佳位置? – sampath

+0

当您完成PDFViewVert的实例时,您可以调用'Runtime.getRuntime().gc();'。 –

+0

也在我编辑的解决方案中按照使实例为空的方式。 –

2

Java的GC确实未提及任何更不一定干净对象。如果目前有足够的内存,它可以决定对它们不做任何事情。

潜在内存泄漏的真正检查可以使用内存分析器来完成。

但你可以尝试更容易检查。尽量减少应用程序的堆大小,并致电System.gc()。这并不能保证触发GC,但是如果它开始移除你的对象,这是一个好兆头,你可能没有内存泄漏。

+0

我试过System.gc(),它没有被触发。我的堆大小是40 MB,在创建了PDFView的20-23个实例后,我得到了outofmemory错误。在我需要调用System.gc()的代码中是否有任何特定的点? – sampath

0

就我个人而言,我认为你最好的选择是使用自定义Adapter,而这样它将重用视图,并且你不会得到pdfview的23个实例。它只会保存一个,它会让你刷卡,而不是击中下一个或上一个。不幸的是,这些设备没有很多的内存,因为你有什么