java.util.LinkedList, вызывающий бесконечный цикл / OutOfMemoryError - PullRequest
0 голосов
/ 18 ноября 2009

Я реализую Cloneable с одним из моих классов, и мне нужно сделать поверхностную копию (да, только поверхностную) java.util.LinkedList, чтобы сделать это. Я пытался использовать

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

но это приводило к остановке моей программы, поэтому я переключился на использование конструктора копирования:

new LinkedList<myType>(myList)

но все равно зависает. Теперь это происходило только с myType, который был enum, но теперь у меня просто была та же ошибка с типом не-enum, хотя теперь я думаю об этом, у этого типа есть внутренний тип enum. это произошло как на jdk 1.6 от Sun, так и на 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 является типом enum, Accidental реализует Cloneable, и его метод clone () воспроизводится ниже. position, restFlag, tripFlag и duration являются примитивами

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

} 

acType - это внутренний тип перечисления, fltPosition - это число с плавающей точкой, они инициализируют только два поля в случайном порядке.

проблема возникает в последней строке метода Note.clone (), когда я вызываю конструктор копирования LinkedList. Раньше это был вызов LinkedList.clone, но я изменил его, чтобы избежать этой проблемы. Вот трассировка стека для этой ошибки (здесь нет ошибки, так как я приостановил поток, когда он замерз, вместо того, чтобы ждать, пока он исчерпает память, но, как вы можете видеть, он был в середине копии LinkedList конструктор)

Линия LinkedList. (Коллекция): 115
Строка Note.clone (): 86
Примечание. Упрощенная (int) строка: 98
Note.split (int, List, List) строка: 179
ManagedPart $ Measure.adjustRemaining (int) строка: 378 ManagedPart $ Measure.add (Примечание) строка: 349
ManagedPart $ Measure.access $ 1 (ManagedPart $ Measure, Note) строка: 345
ManagedPart.addNote (Примечание) строка: 216
PartEditor $ EditPanel $ 3.actionPerformed (ActionEvent) строка: 104
JButton (AbstractButton) .fireActionPerformed (ActionEvent) строка: 2012
AbstractButton $ Handler.actionPerformed (ActionEvent) строка: 2335 Строка DefaultButtonModel.fireActionPerformed (ActionEvent): 404
Строка DefaultButtonModel.setPressed (логическая): 259
Строка BasicButtonListener.mouseReleased (MouseEvent): 253
Строка JButton (Component) .processMouseEvent (MouseEvent): 6108
Строка JButton (JComponent) .processMouseEvent (MouseEvent): 3276
Строка JButton (Component) .processEvent (AWTEvent): 5873
Строка JButton (контейнер) .processEvent (AWTEvent): 2105
Строка JButton (Component) .dispatchEventImpl (AWTEvent): 4469
Строка JButton (контейнер) .dispatchEventImpl (AWTEvent): 2163
Строка JButton (Component) .dispatchEvent (AWTEvent): 4295
Строка LightweightDispatcher.retargetMouseEvent (Component, int, MouseEvent): 4461
Строка LightweightDispatcher.processMouseEvent (MouseEvent): 4125 Строка LightweightDispatcher.dispatchEvent (AWTEvent): 4055
Строка MusedDesktopClient (Container) .dispatchEventImpl (AWTEvent): 2149
MusedDesktopClient (Window) .dispatchEventImpl (AWTEvent) строка: 2478
Строка MusedDesktopClient (Component) .dispatchEvent (AWTEvent): 4295
Строка EventQueue.dispatchEvent (AWTEvent): 604
Строка EventDispatchThread.pumpOneEventForFilters (int): 275
Строка EventDispatchThread.pumpEventsForFilter (int, Conditional, EventFilter): 200
Строка EventDispatchThread.pumpEventsForHierarchy (int, Conditional, Component): 190
Строка EventDispatchThread.pumpEvents (int, Conditional): 185 Строка EventDispatchThread.pumpEvents (Условно): 177
Строка EventDispatchThread.run (): 138

Также недавно у меня была похожая проблема с конструкцией LinkedList в первой строке Note.clone () i. е.

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

вот трассировка стека для этого:

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

Ответы [ 3 ]

2 голосов
/ 18 ноября 2009

В 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>());
0 голосов
/ 19 ноября 2009

Хорошо, так что я понял это. Я думал, что делаю что-то, что вызывает бесконечный цикл в LinkedList, но на самом деле произошло то, что я написал бесконечный цикл, который включал вызовы методов LinkedList, и просто случалось так, что всякий раз, когда я приостанавливал поток или система заканчивалась памяти, это было во время выполнения метода LinkedList.
По-видимому, для их выполнения требуется больше времени, чем для остальной части кода внутри цикла или чего-то еще. Поскольку он всегда был в LinkedList, когда я смотрел трассировку стека, я предполагал, что каким-то образом нарушаю LinkedList, когда на самом деле мой сломанный код просто несколько раз вызывал методы LinkedList, пока я не остановил его или не исчерпал память.

0 голосов
/ 18 ноября 2009

Вы проверили параметры выделения памяти для JVM? В частности -Xms и -Xmx. Вы могли бы просто заполнить всю память, выделенную по умолчанию. Можете ли вы попробовать с

-Xms256m -Xmx1024m

и посмотреть, не получится ли там же?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...