Накопительный пакет памяти Java static [duplicate]

Чтобы предложить лучшее решение, я могу сказать, что обнаружил следующий метод:

parseFloat((0.1 + 0.2).toFixed(10)) => Will return 0.3

Позвольте мне объяснить, почему это лучшее решение. Как упоминалось выше в других ответах, рекомендуется использовать готовые для использования функции Javascript toFixed () для решения проблемы. Но, скорее всего, вы столкнетесь с некоторыми проблемами.

Представьте, что вы собираетесь добавить два числа с плавающей запятой, такие как 0.2 и 0.7, вот оно: 0.2 + 0.7 = 0.8999999999999999.

Ваш ожидаемый результат 0.9 означает, что в этом случае вам нужен результат с точностью до 1 цифры. Поэтому вы должны были использовать (0.2 + 0.7).tofixed(1), но вы не можете просто указать определенный параметр toFixed (), поскольку он зависит от заданного числа, например

`0.22 + 0.7 = 0.9199999999999999`

. В этом примере вам нужна точность в 2 цифры так что это должно быть toFixed(2), так что должно быть параметром для каждого заданного числа с плавающей запятой?

Вы могли бы сказать, что пусть это будет 10 в каждой ситуации:

(0.2 + 0.7).toFixed(10) => Result will be "0.9000000000"

Черт! Что вы собираетесь делать с этими нежелательными нулями после 9? Пришло время преобразовать его в float, чтобы сделать его по вашему желанию:

parseFloat((0.2 + 0.7).toFixed(10)) => Result will be 0.9

Теперь, когда вы нашли решение, лучше предложить его как функцию:

function floatify(number){
       return parseFloat((number).toFixed(10));
    }
 
function addUp(){
  var number1 = +$("#number1").val();
  var number2 = +$("#number2").val();
  var unexpectedResult = number1 + number2;
  var expectedResult = floatify(number1 + number2);
  $("#unexpectedResult").text(unexpectedResult);
  $("#expectedResult").text(expectedResult);
}
addUp();
input{
  width: 50px;
}
#expectedResult{
color: green;
}
#unexpectedResult{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="number1" value="0.2" onclick="addUp()" onkeyup="addUp()"/> +
<input id="number2" value="0.7" onclick="addUp()" onkeyup="addUp()"/> =
<p>Expected Result: <span id="expectedResult"></span></p>
<p>Unexpected Result: <span id="unexpectedResult"></span></p>

Вы можете использовать его следующим образом:

var x = 0.2 + 0.7;
floatify(x);  => Result: 0.9
25
задан Mifeet 1 May 2016 в 09:12
поделиться

2 ответа

Есть несколько вещей о стеках потоков, о которых говорит спецификация Java . Среди прочего:

  • В каждом потоке виртуальной машины Java есть отдельный стек виртуальной машины Java, созданный одновременно с потоком.
  • Поскольку стек виртуальной машины Java никогда не манипулировать напрямую, кроме как нажимать и поп-фреймы, кадры могут быть выделены в кучу. Память для стека виртуальной машины Java не обязательно должна быть непрерывной.
  • Спецификация позволяет стекам виртуальной машины Java либо иметь фиксированный размер, либо динамически расширять и сжимать, как требуется при вычислении.

Теперь, если мы сосредоточимся на реализациях JVM, таких как HotSpot, мы можем получить дополнительную информацию. Вот несколько фактов, которые я собрал из разных источников:

  • Минимальный размер стека в HotSpot для потока кажется фиксированным. Это то, к чему относится вышеупомянутая опция -Xss. (Источник)

В Java SE 6 значение по умолчанию для Sparc равно 512k в 32-разрядной виртуальной машине и 1024k в 64-разрядной VM , ... Вы можете уменьшить размер стека, выполнив опцию -Xss. ... 64k - это наименьшее количество пространства стека, разрешенного для потока.

  • JRockit выделяет память отдельно от кучи, где расположены стеки. (Источник)

Обратите внимание, что JVM использует больше памяти, чем просто кучу. Например, методы Java, стеки потоков и собственные дескрипторы выделяются в памяти отдельно от кучи, а также внутренние структуры данных JVM.

  • Прямое сопоставление между Java Thread и родной OS Thread в HotSpot. (Источник) .
  • Но стек потоков Java в HotSpot управляется программным обеспечением, это не собственный поток стека ОС. (Источник)

Он использует отдельный стек программного обеспечения для передачи аргументов Java, в то время как собственный C-стек используется самой VM. Ряд внутренних переменных JVM, таких как счетчик программ или указатель стека для потока Java, хранятся в переменных C, которые не гарантируются всегда в аппаратных регистрах. Управление этими структурами интерпретатора программного обеспечения потребляет значительную долю общего времени выполнения.

  • JVM также использует тот же стек потока Java для собственных методов и вызовов времени выполнения JVM (например, загрузка классов) , (Источник) .
  • Интересно, что даже выделенные объекты иногда могут быть помещены в стек вместо кучи в качестве оптимизации производительности. (Источник)

JVM могут использовать метод, называемый escape-анализом, с помощью которого они могут сказать, что некоторые объекты остаются ограниченными одним потоком для всего их время жизни, и это время жизни ограничено временем жизни данного кадра стека. Такие объекты могут быть надежно выделены в стеке вместо кучи.

И поскольку изображение стоит тысячи слов, вот один из Джеймс Блум


Теперь, отвечая на некоторые из ваших вопросов:

Как JVM знает, как могут быть созданы потоки?

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

Создает ли Java стек для каждого потока при его создании?

Как упоминалось ранее, поток каждой виртуальной машины Java имеет собственный стек виртуальной машины Java, созданный одновременно с потоком. (Источник) .

Если да, то где именно стек находится в памяти?

Как указано выше, спецификация Java позволяет хранить память стека на куче, технически говоря. Но, по крайней мере, JRockit JVM использует другую часть памяти.

Создает ли JVM стек из собственной памяти или предварительно выделяет раздел области управляемой памяти для стека?

Стек управляется JVM, потому что спецификация Java предписывает , как он должен себя вести: В стеке Java Virtual Machine хранятся фреймы (§2.6). Стек виртуальной машины Java аналогичен стеку обычного языка . Одним из исключений являются стеки Native Method, используемые для методов native. Подробнее об этом еще раз в в спецификации .

44
ответ дан Community 1 September 2018 в 03:51
поделиться

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

Дальнейшее чтение .

Итак, чтобы ответить на ваши вопросы:

Создает ли Java стек для каждого потока при его создании?

Да.

Если да, то где именно стек находится в памяти?

В выделенной памяти JVM, но не в куче.

Если да, то как JVM знает, как могут быть созданы потоки?

Это не так.

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

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

EDIT:

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

4
ответ дан Daniel 1 September 2018 в 03:51
поделиться
Другие вопросы по тегам:

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