Испытание случайных длинных задержек сборки "мусора", почему?

Вам нужно подождать, пока ваше изображение загрузится, прежде чем вы сможете нарисовать его на холсте.

Для этого просто используйте обработчик события load вашего элемента :

// create a new image
var img = new Image();
// declare a function to call once the image has loaded
img.onload = function(){
  var canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  var context = canvas.getContext('2d');
  context.drawImage(img, 0,0);
  var dataURL = canvas.toDataURL();
  // now you can do something with the dataURL
  doSomething(dataURL);
}
// now set the image's src
img.src = "http://somerandomWebsite/picture.png";

Кроме того, для холста 'context.toDataURL() и context.getImageData для работайте правильно, вы должны получить свой ресурс изображения в соответствии с кросс-оригинальным способом , в противном случае холст «испорчен», что означает, что любой метод получения данных с пикселями будет заблокирован.

  • Если ваше изображение поступает с одного и того же сервера, нет проблем.
  • Если ваше изображение подано с внешнего сервера, убедитесь, что оно позволяет вашим в своих кросс-начальных заголовках и установить img.crossOrigin на "use-credentials".
  • Если сервер разрешает анонимные запросы, вы можете установить img.crossOrigin на "anonymous".

Nota Bene : Сервер CORS отправляется сервером, а атрибут cross-origin сообщает, что вы хотите использовать CORS для получения данных изображения, и вы не сможете обойти его, если сервер установлен неправильно. Кроме того, некоторые UserAgents (IE & amp; Safari) до сих пор не реализовали этот атрибут.

Edge Case : Если некоторые из ваших изображений находятся на вашем сервере, а некоторые из них соответствуют требованиям CORS один, тогда вы можете захотеть использовать обработчик события onerror, который должен срабатывать, если вы установите атрибут cross-origin на "anonymous" на сервере без CORS.

function corsError(){
  this.crossOrigin='';
  this.src='';
  this.removeEventListener('error', corsError, false);
} 
img.addEventListener('error', corsError, false);

16
задан Michael Myers 23 February 2009 в 20:54
поделиться

12 ответов

Оказывается, что проблема состояла в том, что "куча" становилась выгруженной к диску, и задержка была GC Java, имеющим необходимость ожидать его, чтобы быть загруженной назад.

Решенный (главным образом) установкой Linux' "swappiness" параметр к 0.

10
ответ дан 30 November 2019 в 22:17
поделиться

В целом трудно разобраться в настройке GC при требовании такой большой "кучи".

Однако большая часть GC зависает, время вызывается копированием памяти объектов, которые выживают через молодые сборки "мусора".

Ваш ConcurrentLinkedHashMap, инициализированный со всеми постоянными объектами памяти внезапно? Или это медленно становится больше, поскольку приложение продолжает бежать? Если это - последний, может быть трудно сократить Ваш GC, подвешивают времена, так как существуют объекты, которые всегда выживают. Если это будет первый, то необходимо будет измерить штатное поколение с размером постоянных объектов + приблизительно 20% и удостовериться, что молодой генерал является достаточно крупным, чтобы не отставать от временных объектов, которые создаются в ходе приложения.

3
ответ дан 30 November 2019 в 22:17
поделиться

Возможно, предел производительности 200 мс слишком строг, и необходимо ли справиться со сборкой "мусора" самостоятельно? Вы попробовали это большим пределом?

1
ответ дан 30 November 2019 в 22:17
поделиться

Со времен кажется, что GC на самом деле не работает все время (см. пользовательские времена), поэтому большую часть времени это ожидает.

Просто произвольное предположение: Разве это не подкачивает? Сколько памяти машина имеет? Сколько из него процесс Java получает (размер резидентного набора)?

Редактирование: почему это ожидание:

Взгляд на это (из Вашей расшифровки стенограммы)

[Times: user=0.39 sys=0.01, real=12.96 secs]

Это означает, что (я предполагаю с начала в конец GC), 12 (почти 13), секунды передали. Из этих 13 секунд.39 был потрачен, работая в непривилегированном режиме.01 был потрачен, работая в привилегированном режиме. Если метод сбора времени не полностью испорчен (т.е. числа действительно представляют время выполнения процесса/потока GC), это означает по крайней мере 12 секунд, ожидая.

6
ответ дан 30 November 2019 в 22:17
поделиться

Если у Вас есть строгие требования синхронизации, возможно, необходимо зарегистрироваться Система реального времени Java .

RTSJ / Java РТС обеспечивает:

набор API, семантический Java улучшения VM и модификации слоя JVM к ОС, которые позволяют Java-разработчикам правильно рассуждать об и управлять временным поведением JAVA-приложений.

0
ответ дан 30 November 2019 в 22:17
поделиться

Можно ли отправить/связать на код реализации ConcurrentLinkedHashMap? Если это - реализация, я отправил, откройте билет на странице проекта, таким образом, мы можем отладить его вместе. В противном случае знание деталей Вашей реализации помогло бы определить, где проблема могла бы лечь.

0
ответ дан 30 November 2019 в 22:17
поделиться

JVM на 9 ГБ! Никогда замечаемый это прежде! Я думаю Ваши 10 секунд. паузы довольно нормальны. видят это (возможно, Вы считали его уже...)

0
ответ дан 30 November 2019 в 22:17
поделиться

Вы запустили свое приложение через профилировщика, чтобы видеть, что то, что Вы думаете, происходит относительно memeory, то, что на самом деле происходит?

Одна вещь я делаю, когда я изучаю, это - использование профилировщик Netbeans (хотя любой профилировщик должен дать это Вам), взгляд на живые байты (выделение памяти), и посмотрите, являются ли те, которые имеют большую сумму выделенных байтов и выделенного objectd, тем, что я ожидаю и происхожу из того, где я ожидаю.

можно также, вероятно, использовать профилировщика для рассмотрения эффекта настройка имеет, запускает приложение без любого tuing args, и затем добавляет настройку args и выполняет его снова и видит то, что продолжает память.

0
ответ дан 30 November 2019 в 22:17
поделиться

Может быть очень трудно сказать без фактического наблюдения и в некоторых случаях профилирования кода.

Реализовали Вас, завершают () для какого-либо из Ваших объектов? Это вызовет большой штраф GC. Также было бы интересно видеть тестовый прогон с "кучей", возможно, 6 Концертов, если бы Вы получаете непропорциональное улучшение производительности, это указало бы, что GC перегружается для памяти.

0
ответ дан 30 November 2019 в 22:17
поделиться

Я думаю, что Ваше внимание могло бы быть немного неверно направлено.

Проводят немного времени в профилировщике, находящем Ваши самые большие горячие точки выделения. Если существует всего несколько мест в Вашем коде, где большинство Ваших выделений происходит, попытайтесь использовать пул объектов вместо того, чтобы всегда создать новые объекты.

классы Набора и StringBuilders являются великими кандидатами на объединение. При возврате их пулу назовите collection.clear () или stringbuilder.setLength (0) методы, так, чтобы они были готовы к потреблению, когда следующая вызывающая сторона хочет получить их от пула.

лучший способ настроить GC путем создания меньшего количества объектов. Существует много стратегий устранения выделений, и объединение является только одним из них (хотя одно из моего избранного).

ОБНОВЛЕНИЕ: это были пять лет, с тех пор как я записал этот ответ, и мое мнение об объединении главным образом изменилось. Назад, когда я записал этот ответ в 2009, я мог часто использовать пулинг объектов (даже простых объектов как StringBuilder) для ускорения трудных внутренних циклов с большим количеством выделений. В эти дни более трудно найти случаи, где объединение не делает ситуацию хуже. Я почти никогда не использую пулы ни для чего кроме потоков или соединений. Все еще, хотя, это - хороший инструмент, чтобы иметь в Вашем распоряжении, даже если Вы часто не используете его.

0
ответ дан 30 November 2019 в 22:17
поделиться
-1
ответ дан 30 November 2019 в 22:17
поделиться

Я думаю, что у вас есть ошибка UseConcMarkSweepGC и NewRatio . Поскольку ваше новое пространство далеко не одна десятая от -Jmx = 9G . Ошибка включает обходной путь (NewSize в абсолютном размере).

Другой флаг, который может быть очень важен для вас, - это CMSInitiatingOccupancyFraction . Он установлен на 92% в java6 и 68% в java5. Если старое пространство становится больше, пул потоков CMS начнет выполнять свою работу. Если у вас есть CPU, который нужно потратить, нет опасности иметь live-set, превышающий исходную долю.

Было бы неплохо, если бы вы включили статистику GC после того, как исправили проблему подкачки памяти.

1
ответ дан 30 November 2019 в 22:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: