Frage

OK, ich schreibe also ein Programm, das leider eine große Datenstruktur verwenden muss, um seine Arbeit zu vervollständigen, aber es fällt bei seiner Initialisierung mit einem "aus Speicherfehler". Obwohl ich ganz verstehe, was das bedeutet und warum es ein Problem ist, habe ich Schwierigkeiten, es zu überwinden, da mein Programm diese große Struktur verwenden muss und ich keinen anderen Weg kenne, um sie zu speichern.

Das Programm indiziert zunächst einen großen Korpus von Textdateien, die ich zur Verfügung stelle. Das funktioniert gut.

Anschließend wird dieser Index verwendet, um ein großes 2D -Array zu initialisieren. Dieses Array hat n² -Einträge, wobei "n" die Anzahl der eindeutigen Wörter im Textkörper ist. Für den relativ kleinen Teil teste ich es auf (ca. 60 Dateien), es muss ungefähr 30.000 x 30.000 Einträge vornehmen. Dies wird wahrscheinlich größer sein, sobald ich es auch auf meinem vollständigen Korpus geführt habe.

Es schlägt jedes Mal, nachdem es Indizes indexiert, konsequent fehl, während es die Datenstruktur initialisiert (um später bearbeitet zu werden).

Dinge, die ich getan habe, umfassen:

  • Überarbeiten Sie meinen Code, um einen Primitiv zu verwenden int[] anstelle einer TreeMap
  • eliminieren redundante Strukturen usw. ...
  • Außerdem habe ich das Programm mit ausgeführt-Xmx2g Mein zugewiesener Gedächtnis zu maximieren

Ich bin ziemlich zuversichtlich, dass dies keine einfache Codelösung sein wird, sondern höchstwahrscheinlich einen sehr neuen Ansatz erfordern wird. Ich suche, was dieser Ansatz ist, irgendwelche Ideen?

Danke, B.

War es hilfreich?

Lösung

Es klingt nach (einige Annahmen darüber, wofür Sie Ihr Array verwenden). Die meisten Einträge werden 0 sein spärliche Matrix Darstellung.

Wenn du wirklich haben so viele Einträge (Ihr aktuelles Array ist irgendwo bereits über 3 Gigabyte, Selbst wenn Sie keinen Overhead annehmen), müssen Sie eine Art On-Disk-Speicher oder ein faullades/entladeer System verwenden.

Andere Tipps

Es gibt mehrere Ursachen für aus Gedächtnisproblemen.

Erstens ist der einfachste Fall, dass Sie einfach mehr Haufen benötigen. Sie verwenden 512m maximaler Haufen, wenn Ihr Programm mit 2G korrekt funktionieren kann. Erhöhung ist mit -Xmx2048m Als JVM -Option und es geht dir gut. Achten Sie auch darauf, dass 64 -Bit -VMs je nach Make -up dieser Daten bis zu dem doppelten Speicher von 32 Bit -VMs verwenden.

Wenn Ihr Problem nicht so einfach ist, können Sie die Optimierung betrachten. Objekte durch Primitiven ersetzen und so weiter. Dies könnte eine Option sein. Ich kann nicht wirklich sagen, was Sie gepostet haben.

Letztendlich kommen Sie zu einer Kreuzung, auf der Sie eine Wahl treffen müssen Virkulierung und Partitionierung.

Virtualisierung In diesem Zusammenhang bedeutet einfach eine Form des Totelns, dass es mehr Gedächtnis gibt als es gibt. Betriebssysteme verwenden dies mit virtuellen Adressräumen und verwenden den Festplattenraum als zusätzlichen Speicher. Dies könnte bedeuten, dass nur einen Teil der Datenstruktur gleichzeitig im Speicher aufbewahrt und den Rest bis zum Sekundärspeicher (z. B. Datei oder Datenbank) anhält.

Partitionierung spaltet Ihre Daten über mehrere Server hinweg (entweder real oder virtuell). Wenn Sie beispielsweise Aktiengeschäfte auf der NASDAQ verfolgen, können Sie Aktiencodes einstellen, beginnend mit "A" auf Server1, "B" auf Server2 usw. Sie müssen einen angemessenen Ansatz finden, um Ihre Daten so zu schneiden, dass Sie reduzieren Oder beseitigen Sie die Notwendigkeit einer Kreuzkommunikation, da diese Kreuzkommunikation Ihre Skalierbarkeit einschränkt.

Wenn Sie also 30.000 Wörter und 30k x 30k Kombinationen von Wörtern haben, können Sie es in vier Server aufteilen:

  • Bin x am
  • Bin x nz
  • Nz x am
  • Nz x nz

Das ist nur eine Idee. Auch hier ist es schwer, Einzelheiten zu kennen.

Dies ist ein häufiges Problem, das sich mit großen Datensätzen befasst. Sie können so viel optimieren, wie Sie möchten, aber das Gedächtnis wird (wahrscheinlich) niemals ausreichen, und sobald der Datensatz ein wenig mehr wächst, werden Sie noch geraucht. Die skalierbarste Lösung besteht einfach darin, weniger im Speicher zu halten, an Stücken zu arbeiten und die Struktur auf der Festplatte (Datenbank/Datei) zu bestehen.

Wenn Sie für jeden Wert in Ihrem 2D -Array nicht volle 32 Bit (Ganzzahl) benötigen, würde ein kleinerer Typ wie ein Byte den Trick machen? Außerdem sollten Sie ihm so viel Haufen wie möglich geben - 2 GB ist für ein modernes System immer noch relativ klein. RAM ist billig, besonders wenn Sie erwarten, viel Verarbeitung in Memory durchzuführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top