java.util.LinkedList 导致无限循环/OutOfMemoryError

标签 java

我正在使用我的一个类实现 Cloneable,并且我需要制作 java.util.LinkedList 的浅拷贝(是的,只是浅表)来执行此操作。我尝试使用

myList.clone() //myList is a java.util.LinkedList<myType>

但这导致我的程序停止,所以我转而使用复制构造函数:

new LinkedList<myType>(myList)

但它仍然挂起。现在,这只发生在作为枚举的 myType 上,但现在我对非枚举类型遇到了同样的错误,尽管现在我认为该类型具有内部枚举类型。 Sun 的 jdk 1.6 和 openjdk 1.6 上都发生过这种情况。我确信我做错了什么,但我不知道我会做什么会破坏 LinkedList。它不会抛出异常,直到它最终耗尽内存(通常我会在这种情况发生之前杀死它)。不管怎样,有什么想法可能导致这个问题吗?

这是克隆方法:

public Note clone(){
    List<Accidental> retAcc=new LinkedList<Accidental>();
    for(Accidental acc:accidentals)retAcc.add(acc.clone());
    return new Note(retAcc,position,restFlag,new LinkedList<TieType>(beginTies),new LinkedList<TieType>(endTies),tripFlag,duration);
}

TieType 是一个枚举类型,Accidental 实现了 Cloneable,其 clone() 方法如下所示。 position、restFlag、tripFlag 和uration 都是原语

public Accidental clone(){
    return new Accidental(acType,fltPosition);

} 

acType是一个内部枚举类型,fltPosition是一个float,它们初始化了唯一的两个字段。

当我调用 LinkedList 复制构造函数时,问题发生在 Note.clone() 方法的最后一行。这曾经是对 LinkedList.clone 的调用,但我更改了它以试图避免此问题。这是此错误的堆栈跟踪(这里没有错误,因为我在线程卡住时挂起线程,而不是等待它耗尽内存,但如您所见,它位于 LinkedList 副本的中间构造函数)

LinkedList.(Collection) line: 115
Note.clone() line: 86
Note.simplify(int) line: 98
Note.split(int, List, List) line: 179
ManagedPart$Measure.adjustRemaining(int) line: 378 ManagedPart$Measure.add(Note) line: 349
ManagedPart$Measure.access$1(ManagedPart$Measure, Note) line: 345
ManagedPart.addNote(Note) line: 216
PartEditor$EditPanel$3.actionPerformed(ActionEvent) line: 104
JButton(AbstractButton).fireActionPerformed(ActionEvent) line: 2012
AbstractButton$Handler.actionPerformed(ActionEvent) line: 2335 DefaultButtonModel.fireActionPerformed(ActionEvent) line: 404
DefaultButtonModel.setPressed(boolean) line: 259
BasicButtonListener.mouseReleased(MouseEvent) line: 253
JButton(Component).processMouseEvent(MouseEvent) line: 6108
JButton(JComponent).processMouseEvent(MouseEvent) line: 3276
JButton(Component).processEvent(AWTEvent) line: 5873
JButton(Container).processEvent(AWTEvent) line: 2105
JButton(Component).dispatchEventImpl(AWTEvent) line: 4469
JButton(Container).dispatchEventImpl(AWTEvent) line: 2163
JButton(Component).dispatchEvent(AWTEvent) line: 4295
LightweightDispatcher.retargetMouseEvent(Component, int, MouseEvent) line: 4461
LightweightDispatcher.processMouseEvent(MouseEvent) line: 4125 LightweightDispatcher.dispatchEvent(AWTEvent) line: 4055
MusedDesktopClient(Container).dispatchEventImpl(AWTEvent) line: 2149
MusedDesktopClient(Window).dispatchEventImpl(AWTEvent) line: 2478
MusedDesktopClient(Component).dispatchEvent(AWTEvent) line: 4295
EventQueue.dispatchEvent(AWTEvent) line: 604
EventDispatchThread.pumpOneEventForFilters(int) line: 275
EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 200
EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 190
EventDispatchThread.pumpEvents(int, Conditional) line: 185 EventDispatchThread.pumpEvents(Conditional) line: 177
EventDispatchThread.run() line: 138

最近,我在 Note.clone() i 的第一行中构建 LinkedList 时也遇到了类似的问题。 e.

List<Accidental> retAcc=new LinkedList<Accidental>();

这是堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space at java.util.LinkedList.(LinkedList.java:95) at com.mused.util.noteMgmt.Note.clone(Note.java:84) at com.mused.util.noteMgmt.Note.simplify(Note.java:98) at com.mused.util.noteMgmt.Note.split(Note.java:179) at com.mused.util.noteMgmt.ManagedPart$Measure.adjustRemaining(ManagedPart.java:378) at com.mused.util.noteMgmt.ManagedPart$Measure.insert(ManagedPart.java:335) at com.mused.util.noteMgmt.ManagedPart.insertNote(ManagedPart.java:223) at com.mused.gui.editor.PartEditor.currentIndexChanged(PartEditor.java:161) at com.mused.gui.NoteViewer.fireIndexChangeEvent(NoteViewer.java:178) at com.mused.gui.NoteViewer.setCurrentIndex(NoteViewer.java:417) at com.mused.gui.NoteViewer.updateSelected(NoteViewer.java:627) at com.mused.gui.NoteViewer.mouseMoved(NoteViewer.java:725) at java.awt.Component.processMouseMotionEvent(Component.java:6153) at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:3294) at java.awt.Component.processEvent(Component.java:5877) at java.awt.Container.processEvent(Container.java:2105) at java.awt.Component.dispatchEventImpl(Component.java:4469) at java.awt.Container.dispatchEventImpl(Container.java:2163) at java.awt.Component.dispatchEvent(Component.java:4295) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4461) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4138) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4055) at java.awt.Container.dispatchEventImpl(Container.java:2149) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4295) at java.awt.EventQueue.dispatchEvent(EventQueue.java:604) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177) at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

最佳答案

LinkedList::clone() 没有任何问题。如果它挂起,那么您的列表已损坏,以某种方式形成了循环链接。这是 java/util/LinkedList.java 中唯一相关代码的摘录:

for (Entry e = header.next; e != header; e = e.next)
    clone.add(e.element);

这与 LinkedList::toArray() 使用的算法相同,因此如果 clone() 挂起,那么也应该这样:

System.out.println(Arrays.toString(myList.toArray()));

如果挂起,则您的列表已损坏。最有可能的罪魁祸首是同步问题。 LinkedList 不是线程安全的。尝试像这样同步您的声明:

List<myType> myList = Collections.synchronizedList(new LinkedList<myType>());

关于java.util.LinkedList 导致无限循环/OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1753694/

相关文章:

java - 如何将本地项目(不是 jar)添加为 Maven 项目的依赖项

java - 如何在我的 gwt 应用程序中导入 java.security.*

java - Java中这些整数是先转换为 float 再相加还是先相加​​再转换为 float ?

java - 使用反射覆盖 2 + 2 = 5

java - 为 JComboBox 显示一个不可选择的默认值

java - 允许自动查询的网络搜索 API

java - 我想在 .wav 中以 8000hz 的采样率在 android 手机中录制 6 秒的声音

java - MALLET:如何实现基于crf的编辑距离?

java - 如何解决不同类型的集合

java - 具有 HTTP Location header 的 ResponseEntity 不会导致重定向