我正在Java 5上编写一个客户端Swing应用程序(图形字体设计器).最近,我遇到了错误,因为我对内存使用情况并不保守.用户可以打开无限数量的文件,程序将打开的对象保存在内存中.经过快速研究后,我在5.0 Java虚拟机中找到了人体工程学,其他人在Windows机器上说JVM默认最大堆大小为.java.lang.OutOfMemoryError: Java heap space64MB
鉴于这种情况,我该如何处理这种约束?
我可以使用java的命令行选项增加最大堆大小,但这需要找出可用的RAM并编写一些启动程序或脚本.此外,增加到一些有限的最大值并不能最终摆脱这个问题.
我可以重写我的一些代码来经常将对象持久化到文件系统(使用数据库是一回事)来释放内存.它可以工作,但它可能也很重要.
如果您可以向我指出上述想法的细节或某些替代方案,如自动虚拟内存,动态扩展堆大小,这将是很好的.
使用弱引用是我从未见过的实现,所以我试图弄清楚它们的用例是什么以及实现如何工作.什么时候需要使用WeakHashMap或者WeakReference它是如何使用的?
我是一名Java开发人员已有2年.
但我从来没有在我的代码中写过WeakReference.如何使用WeakReference使我的应用程序更高效,尤其是Android应用程序?
在Kotlin中编写扩展方法很容易:
class A { }
class B {
fun A.newFunction() { ... }
}
Run Code Online (Sandbox Code Playgroud)
但有没有办法创建扩展变量?喜欢:
class B {
var A.someCounter: Int = 0
}
Run Code Online (Sandbox Code Playgroud) 我一直试图理解不同参考文献之间的区别,但理论并没有激发任何想法让我想象相同.
有谁能请简要解释一下不同的参考文献?
每个例子都会做得更好.
我有一个缓存,它具有对缓存对象的软引用.我正在尝试为类的行为编写功能测试,这些类使用缓存专门用于清除缓存对象时发生的情况.
问题是:我似乎无法可靠地获得要清除的软引用.简单地使用一堆内存并不能解决问题:在清除任何软引用之前,我得到一个OutOfMemory.
有没有办法让Java更加急切地清理软引用?
在这里找到:
"虽然在抛出OutOfMemoryError之前所有的SoftReferences都会被清除,但是理论上它们不会导致OOME."
那么这是否意味着上面的场景必须意味着我的内存泄漏,某些类在我的缓存对象上持有一个硬引用?
我目前正在尝试诊断应用程序中的缓慢内存泄漏.我到目前为止的事实如下.
尽管只是被WeakReferences引用(根据Eclipse Memory Analyzer Tool),但是可能导致这些Foo类无法收集的原因是什么?
EDIT1:
@mindas我使用的WeakReference等同于以下示例代码.
public class FooWeakRef extends WeakReference<Foo>
{
public long longA;
public long longB;
public String stringA;
public FooWeakRef(Foo xiObject, ReferenceQueue<Foo> xiQueue)
{
super(xiObject, xiQueue);
}
}
Run Code Online (Sandbox Code Playgroud)
Foo没有终结器,只要没有清除WeakRefs,任何终结器都不会被考虑.当一个对象弱可达时,它不能最终确定.有关详情,请参阅此页面.
@kasten在对象可最终化之前清除弱引用.我的堆转储显示这没有发生.
@jarnbjo我引用WeakReference Javadoc:
"假设垃圾收集器在某个时间点确定一个对象是弱可达的.那时它将原子地清除对该对象的所有弱引用以及对该对象可从其访问的任何其他弱可达对象的所有弱引用通过一系列强大而柔软的参考资料."
这告诉我,GC应该检测到我的Foo对象是"弱可达"和"当时"清除弱引用这一事实.
编辑2
@j flemm - 我知道40mb听起来并不多,但我担心4天内40mb意味着100天内4000mb.我读过的所有文档都表明,弱可达的对象不应该闲置几天.因此,我对如何在没有引用显示在堆转储中时强烈引用对象的任何其他解释感兴趣.
当一些悬空Foo对象存在时,我将尝试分配一些大对象,并查看JVM是否收集它们.但是,此测试需要几天时间才能完成设置.
编辑3
@jarnbjo - 我知道我不能保证JDK何时会注意到一个对象是弱可达的.但是,我认为重载4天的应用程序会为GC提供足够的机会来注意我的对象是弱可达的.4天后,我强烈怀疑其余的弱引用对象已经以某种方式泄露.
编辑4
@j flemm - 多数民众赞成真有意思!只是为了澄清,你是说GC正在你的应用程序上发生并且没有清除Soft/Weak refs?您能否告诉我有关您正在使用的JVM + GC配置的更多详细信息?我的应用程序使用80%堆的内存条来触发GC.我假设任何旧的GC的GC都会清除Weak refs.一旦内存使用率高于更高的阈值,您是否建议GC仅收集弱引用?这个更高的限制是否可配置?
编辑5
@j flemm - 关于在SoftRefs之前清除WeakRefs的评论与Javadoc一致,其中声明:SoftRef:"假设垃圾收集器在某个时间点确定一个对象可以轻柔地到达.那时它可以选择清除原子地对该对象的所有软引用以及对任何其他可通过一系列强引用访问该对象的软可引用对象的所有软引用.同时或稍后它会将那些新清除的软引用排入队列在参考队列中注册."
WeakRef:"假设垃圾收集器在某个时间点确定一个对象是弱可达的.那时它将原子地清除对该对象的所有弱引用以及对该对象的任何其他弱可达对象的所有弱引用可以通过一系列强引用和软引用来访问.同时它将声明所有以前弱可达的对象都可以最终确定.同时或稍后它会将那些新清除的弱引用排入队列.在参考队列中注册."
为清楚起见,您是说当您的应用程序具有超过50%的可用内存时垃圾收集器运行,并且在这种情况下它不会清除WeakRefs?当你的应用程序有超过50%的可用内存时,为什么GC会运行?我认为你的应用程序可能只是产生非常少量的垃圾,当收集器运行时它正在清除WeakRefs而不是SoftRef.
编辑6 …
在Java中有一种优雅的方法可以将所有现有的对象指针设置为null吗?我希望删除一个对象,但它在几个地方注册了一个事件监听器.
我接近它类似于删除任何常见对象的情况,即简单地使引用为null并让垃圾收集器完成其工作.
但是,对于在类中等于null,对该对象的唯一引用是"this".以下类的代码是有效的:
class A{
public A(){
//Init
}
public void method destruct(){
if(someCondition){
this=null; //Is this statement valid? Why / Why not?
}
}
}
Run Code Online (Sandbox Code Playgroud) 我阅读了很多文章,但我不明白 - 在实践中我需要在哪里使用Weak和Phantom参考?软错误引用 - 正如我所理解的那样,是缓存的不错选择.但弱和幻影,我不知道何时使用.请提供我们需要使用它们的实际任务的示例.
java ×9
android ×1
destructor ×1
heap-memory ×1
java-ee ×1
jvm ×1
kotlin ×1
memory-leaks ×1
reference ×1